नीचे लिखे गए कोड के एक टुकड़े का उपयोग करते समय मुझे यह चेतावनी मिल रही है:

//Macro
#define FREEIF(p)            if (p) { free_mem((void*)p); (p) = 0; }

//free_mem function
int free_mem(void *mem_ptr)
{
    if (mem_ptr != NULL)
    {
        free(mem_ptr);
    }
    mem_ptr = NULL;
    return 0;
}


//Use of Macro in my .c file with above declaration and definition of macro.
....
....

{
 FREEIF(temp_ptr);
}

अगर मैं मैक्रो को कॉल करने से पहले "temp_ptr" जैसे if (temp_ptr) {FREEIF(temp_ptr);} के लिए एक चेक जोड़ता हूं, तो मुझे यह चेतावनी नहीं मिलती है।

जैसा कि मैं पहले से ही मैक्रो के अंदर "temp_ptr" की जाँच कर रहा हूँ। मैं सोच रहा हूं कि मुझे यह चेतावनी क्यों मिली।

कोई अंतर्दृष्टि?

0
user3860869 6 अगस्त 2021, 16:19

2 जवाब

सबसे बढ़िया उत्तर

त्रुटि के संबंध में, नियम 2.2 आपके प्रोग्राम में कोई "मृत कोड" नहीं होने के बारे में है।

फ़ंक्शन में, mem_ptr = NULL; स्थानीय चर mem_ptr को शून्य पर सेट करता है, न कि पास किए गए चर को। तो वह कोड लाइन कुछ नहीं करती है। यह त्रुटि का कारण है और यह एक सामान्य शुरुआती अक्सर पूछे जाने वाले प्रश्न हैं, देखें डायनामिक मेमोरी एक्सेस विवरण के लिए केवल फ़ंक्शन के अंदर काम करता है

फ़ंक्शन-जैसे मैक्रो में, पास किए गए पॉइंटर को (p) = 0; द्वारा बदल दिया जाएगा। लेकिन अगर आप इसे शून्य पर सेट करने के बाद पॉइंटर का उपयोग नहीं कर रहे हैं, तो इसे अभी भी "मृत कोड" माना जाता है क्योंकि असाइनमेंट तब सख्ती से व्यर्थ बोल रहा है (हालांकि अच्छा अभ्यास)। हम नहीं बता सकते क्योंकि आपने न तो कॉलिंग कोड पोस्ट किया और न ही वास्तविक सूचक घोषणा।

लेकिन यहाँ कुछ अधिक गंभीर बड़ी तस्वीर के मुद्दे हैं:

  • एक ही समय में MISRA-C और डायनेमिक मेमोरी आवंटन का उपयोग करना निरर्थक है। वे काफी हद तक परस्पर अनन्य हैं। एंबेडेड सिस्टम सामान्य रूप से गतिशील आवंटन का उपयोग नहीं करते हैं, विशेष रूप से नंगे धातु/आरटीओएस एमसीयू अनुप्रयोगों का नहीं जहां इसका बस कोई मतलब नहीं है .

    मिशन-महत्वपूर्ण/सुरक्षा-संबंधी सॉफ़्टवेयर में गतिशील आवंटन विशेष रूप से प्रतिबंधित है। यह न केवल MISRA द्वारा प्रतिबंधित है, बल्कि किसी भी कोडिंग मानक द्वारा प्रतिबंधित है। यह सामान्य सुरक्षा मानकों जैसे IEC 61508, ISO 26262, DO 178 आदि द्वारा भी प्रतिबंधित है।

  • सुरक्षा और MISRA एक तरफ, आपका मैक्रो अभी भी बकवास है क्योंकि free() एक नल पॉइंटर पर एक अच्छी तरह से परिभाषित नो-ऑप है। C17 7.22.3.3 में free की परिभाषा देखें:

    void free(void *ptr); /--/ अगर ptr एक नल पॉइंटर है, तो कोई कार्रवाई नहीं होती है।

    तो सभी मैक्रो प्राप्त करता है कोड को खराब करना और इसे एक अतिरिक्त, व्यर्थ शाखा के साथ धीमा करना है।

यहां सही समाधान यह है कि इस मैक्रो को परमाणु बनाया जाए, फिर एक कदम पीछे हटें और विचार करें कि आप इस परियोजना के साथ क्या कर रहे हैं। आवश्यकताओं से शुरू करें। आपको MISRA-C की आवश्यकता क्यों है, क्या इस परियोजना में किसी को पता है कि वे क्या कर रहे हैं, यदि नहीं - इस परियोजना में सहायता के लिए हमें किसे नियुक्त करना चाहिए। और इसी तरह। आपको MISRA-C के साथ एक परियोजना के लिए टीम में कम से कम एक C अनुभवी की आवश्यकता है अन्यथा परियोजना बर्बाद हो गई है।

1
Lundin 1 सितंबर 2021, 08:14

C में तर्क मान से पारित हैं। इसका मतलब है कि तर्कों के रूप में पारित मान फ़ंक्शन के अंदर दिखाई देने वाले तर्कों के लिए प्रतिलिपि हैं और फ़ंक्शन से तर्कों को संशोधित करने से पास किए गए मूल मानों पर कोई प्रभाव नहीं पड़ता है।

इसलिए, लाइन mem_ptr = NULL; अर्थहीन है (कम से कम यह मान लेना अर्थहीन लगता है कि कोई अपरिभाषित व्यवहार नहीं है जैसे कि आउट-ऑफ-बाउंड्स रीड या डीरेफरेंसिंग अमान्य पॉइंटर्स) क्योंकि mem_ptr फ़ंक्शन के लिए स्थानीय है और मान नहीं है असाइनमेंट के बाद बिल्कुल पढ़ें।

दूसरी ओर, (p) = 0; अर्थहीन नहीं हो सकता क्योंकि p मैक्रो में घोषित नहीं किया गया है, इसलिए यह संदर्भित करेगा कि मैक्रो से पहले क्या घोषित किया गया है और जिसे मैक्रो के आह्वान के बाद पढ़ा जा सकता है।

2
MikeCAT 6 अगस्त 2021, 13:30