#ifdef बनाम #if - जो कोड के विशेष वर्गों को सक्षम / अक्षम करने के लिए एक विधि के रूप में बेहतर / सुरक्षित है?


112

यह शैली का मामला हो सकता है, लेकिन हमारी देव टीम में थोड़ा सा विभाजन है और मुझे आश्चर्य है कि किसी और ने इस मामले पर कोई विचार किया था ...

मूल रूप से, हमारे पास कुछ डिबग प्रिंट स्टेटमेंट हैं, जिन्हें हम सामान्य विकास के दौरान बंद कर देते हैं। व्यक्तिगत रूप से मैं निम्नलिखित करना पसंद करता हूं:

//---- SomeSourceFile.cpp ----

#define DEBUG_ENABLED (0)

...

SomeFunction()
{
    int someVariable = 5;

#if(DEBUG_ENABLED)
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

टीम में से कुछ हालांकि निम्नलिखित पसंद करते हैं:

// #define DEBUG_ENABLED

...

SomeFunction()
{
    int someVariable = 5;

#ifdef DEBUG_ENABLED
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

... उन तरीकों में से कौन सा आपको बेहतर लगता है और क्यों? मेरी भावना यह है कि पहला अधिक सुरक्षित है क्योंकि हमेशा कुछ परिभाषित होता है और ऐसा कोई खतरा नहीं है जो अन्य जगहों को नष्ट कर सकता है।


ध्यान दें: के साथ #if, आप भी इसके #elifविपरीत, एक सुसंगत तरीके से उपयोग कर सकते हैं #ifdef। इस प्रकार, केवल उपयोग करने के बजाय , आदि के साथ #define BLAHउपयोग करें ...#define BLAH 1#if BLAH
एंड्रयू

जवाबों:


82

मेरी शुरुआती प्रतिक्रिया #ifdef, ज़ाहिर है , लेकिन मुझे लगता है कि #ifवास्तव में इसके लिए कुछ महत्वपूर्ण फायदे हैं - यहाँ क्यों है:

सबसे पहले, आप DEBUG_ENABLEDप्रीप्रोसेसर और संकलित परीक्षणों में उपयोग कर सकते हैं । उदाहरण - अक्सर, मैं डिबग सक्षम होने पर अधिक समय चाहता हूं, इसलिए उपयोग करते हुए #if, मैं यह लिख सकता हूं

  DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000);

... के बजाय ...

#ifdef DEBUG_MODE
  DoSomethingSlowWithTimeout(5000);
#else
  DoSomethingSlowWithTimeout(1000);
#endif

दूसरा, यदि आप #defineवैश्विक स्थिरांक से पलायन करना चाहते हैं तो आप बेहतर स्थिति में हैं । #defines आमतौर पर ज्यादातर C ++ प्रोग्रामर द्वारा फॉलो किया जाता है।

और, तीसरा, आप कहते हैं कि आप अपनी टीम में विभाजित हैं। मेरा अनुमान है कि इसका मतलब यह है कि विभिन्न सदस्यों ने पहले से ही अलग-अलग तरीके अपनाए हैं, और आपको मानकीकृत करने की आवश्यकता है। सत्तारूढ़ करने के #ifलिए पसंदीदा विकल्प का मतलब है कि कोड का उपयोग करके #ifdef-और रन को संकलित किया जाएगा - तब भी जब DEBUG_ENABLEDझूठी है। और यह डिबग आउटपुट को ट्रैक करने और हटाने में बहुत आसान है जो तब उत्पन्न होता है जब इसे इसके विपरीत नहीं होना चाहिए।

ओह, और एक मामूली पठनीयता बिंदु। आपको अपने में 0/1 के बजाय सही / गलत का उपयोग करने में सक्षम होना चाहिए #define, और क्योंकि मान एक एकल शाब्दिक टोकन है, यह एक बार है जब आपको इसके चारों ओर कोष्ठक की आवश्यकता नहीं है।

#define DEBUG_ENABLED true

के बजाय

#define DEBUG_ENABLED (1)

डिबगिंग को सक्षम / अक्षम करने के लिए निरंतर का उपयोग नहीं किया जा सकता है, इसलिए #define के साथ एक #ifdef को 0 पर ट्रिगर करना इतना सौम्य नहीं हो सकता है। सत्य / असत्य के लिए, C99 में जोड़े गए थे और C89 / C90 में मौजूद नहीं थे।
माइकल कारमैन

माइकल: वह / वह #ifdef के उपयोग के खिलाफ वकालत कर रहा था ।
जॉन केज

7
हाँ, एक समस्या #ifdefयह है कि यह उन चीजों के साथ काम करता है जो परिभाषित नहीं हैं; चाहे वे जानबूझकर या टाइपो के कारण परिभाषित न हों या आपके पास क्या है।
bames53

6
उत्तर के लिए आपका जोड़ गलत है। #if DEBUG_ENBALEDप्रीप्रोसेसर द्वारा पाई गई त्रुटि नहीं है। यदि DEBUG_ENBALEDपरिभाषित नहीं किया गया है, तो यह निर्देशों 0में टोकन का विस्तार करता है #if
आर .. गिटहब स्टॉप हेल्पिंग आईसीई

6
@R .. कई कंपाइलरों में आप "# DEBUG_ENABLED" के लिए चेतावनी सक्षम कर सकते हैं जब DEBUG_ENABLED परिभाषित नहीं है। GCC में "-Wefef" का उपयोग करें। Microsoft Visual Studio में C4668 को स्तर 1 की चेतावनी के रूप में चालू करने के लिए "/ w14668" का उपयोग करें।
विल

56

वे दोनों छिपे हुए हैं। इसके बजाय, यह करें:

#ifdef DEBUG
#define D(x) do { x } while(0)
#else
#define D(x) do { } while(0)
#endif

फिर जब भी आपको डीबग कोड की आवश्यकता हो, उसे अंदर डालें D();। और आपके कार्यक्रम में छिपे हुए माज़ के साथ प्रदूषित नहीं है #ifdef


6
@MatthieuM। वास्तव में, मुझे लगता है कि मूल संस्करण ठीक था। अर्धविराम की व्याख्या एक खाली कथन के रूप में की जाएगी। हालांकि, अर्धविराम को भूलना इसे खतरनाक बना सकता है।
केसी कुबाल

31

#ifdef अगर टोकन परिभाषित किया गया है, तो बस जाँच करता है

#define FOO 0

फिर

#ifdef FOO // is true
#if FOO // is false, because it evaluates to "#if 0"

20

कई फ़ाइलों में हमारी यही समस्या रही है और "फ़ीचर फ़्लैग" फ़ाइल को शामिल करने की भूल करने वाले लोगों के साथ हमेशा समस्या रही है (41,000 फ़ाइलों के कोडबेस के साथ यह करना आसान है)।

यदि आपके पास फीचर था।

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE 1

#endif // FEATURE_H

लेकिन तब आप हेडर फ़ाइल को file.cpp में शामिल करना भूल गए:

#if COOL_FEATURE
    // definitely awesome stuff here...
#endif

फिर आपको एक समस्या है, संकलक इस मामले में COOL_FEATURE को "झूठे" के रूप में अपरिभाषित करता है और कोड को शामिल करने में विफल रहता है। हाँ gcc एक ऐसे ध्वज का समर्थन करता है जो अपरिभाषित मैक्रोज़ के लिए एक त्रुटि का कारण बनता है ... लेकिन अधिकांश 3rd पार्टी कोड या तो परिभाषित करता है या सुविधाओं को परिभाषित नहीं करता है ताकि यह पोर्टेबल न हो।

हमने इस मामले को ठीक करने का एक पोर्टेबल तरीका अपनाया है और साथ ही एक फीचर की स्थिति के लिए परीक्षण किया है: फ़ंक्शन मैक्रोज़।

यदि आपने उपरोक्त फीचर को बदल दिया है।

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE() 1

#endif // FEATURE_H

लेकिन तब आप फिर से हेडर फ़ाइल को file.cpp में शामिल करना भूल गए:

#if COOL_FEATURE()
    // definitely awseome stuff here...
#endif

अपरिभाषित फ़ंक्शन मैक्रो के उपयोग के कारण पूर्वप्रक्रमक को गलत माना जाएगा।


17

सशर्त संकलन करने के प्रयोजनों के लिए, #if और #ifdef लगभग समान हैं, लेकिन काफी नहीं। यदि आपका सशर्त संकलन दो प्रतीकों पर निर्भर करता है तो #ifdef भी काम नहीं करेगा। उदाहरण के लिए, मान लें कि आपके पास दो सशर्त संकलन प्रतीक हैं, PRO_VERSION और TRIAL_VERSION, आपके पास इसके लिए कुछ हो सकता है:

#if defined(PRO_VERSION) && !defined(TRIAL_VERSION)
...
#else
...
#endif

#Ifdef का उपयोग करना अधिक जटिल हो जाता है, विशेष रूप से काम करने के लिए # भाग प्राप्त करना।

मैं ऐसे कोड पर काम करता हूं जो सशर्त संकलन का बड़े पैमाने पर उपयोग करता है और हमारे पास #if & #ifdef का मिश्रण है। जब भी दो या दो से अधिक प्रतीकों का मूल्यांकन किया जा रहा हो, हम साधारण मामले के लिए # ifdef / # ifndef का उपयोग करते हैं।


1
में #if definedहै कि क्या definedयह एक महत्वपूर्ण शब्द या है?
nmxprime

15

मुझे लगता है कि यह पूरी तरह से शैली का सवाल है। न तो वास्तव में दूसरे पर स्पष्ट लाभ है।

संगति या तो विशेष पसंद से अधिक महत्वपूर्ण है, इसलिए मैं आपको सलाह दूंगा कि आप अपनी टीम के साथ मिलकर एक शैली चुनें, और उससे चिपके रहें।


8

मैं खुद पसंद करता हूं:

#if defined(DEBUG_ENABLED)

चूंकि इससे कोड बनाना आसान हो जाता है, जो विपरीत स्थिति के लिए दिखता है, जो जगह के लिए बहुत आसान है:

#if !defined(DEBUG_ENABLED)

बनाम

#ifndef(DEBUG_ENABLED)

8
व्यक्तिगत रूप से मुझे लगता है कि उस छोटे विस्मयादिबोधक चिह्न को याद करना आसान है!
जॉन केज

6
वाक्य रचना हाइलाइटिंग के साथ? :) सिंटैक्स हाइलाइटिंग में, "ifndef" में "n" को स्पॉट करना बहुत कठिन है क्योंकि यह सभी समान रंग है।
जिम बक

ठीक है मेरा मतलब है कि #ifndef #if की तुलना में स्पॉट करना अधिक आसान है! जब आप #if परिभाषित के खिलाफ तुलना कर रहे हैं तो परिभाषित किया गया है .. लेकिन सभी #if परिभाषित / # दिए गए हैं;
जॉन केज

@JonCage मैं जानता हूँ कि यह इस टिप्पणी के बाद से कुछ साल हो गया है, लेकिन मैं बाहर बात करने के लिए आप इसे लिख सकते हैं के रूप में करना चाहते हैं #if ! definedबनाने के लिए !अधिक प्रमुख और याद आती है के लिए कड़ी मेहनत।
चरण

@ चित्र - यह निश्चित रूप से एक सुधार की तरह लग रहा है :)
जॉन केज

7

यह स्टाइल की बात है। लेकिन मैं इसे करने के अधिक संक्षिप्त तरीके की सलाह देता हूं:

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print
#endif

debug_print("i=%d\n", i);

आप एक बार ऐसा करते हैं, फिर हमेशा डिबग_प्रिंट () का उपयोग करें या तो प्रिंट करें या कुछ भी न करें। (हां, यह दोनों मामलों में संकलित करेगा।) इस तरह, आपका कोड प्रीप्रोसेसर निर्देशों के साथ नहीं होगा।

यदि आपको चेतावनी मिलती है "अभिव्यक्ति का कोई प्रभाव नहीं है" और इससे छुटकारा पाना चाहते हैं, तो यहां एक विकल्प है:

void dummy(const char*, ...)
{}

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print dummy
#endif

debug_print("i=%d\n", i);

3
शायद मुद्रण मैक्रो के बाद का सबसे अच्छा उदाहरण नहीं था - हम वास्तव में यह हमारे पहले से ही हमारे अधिक मानक डिबग कोड के लिए कोडबेस में करते हैं। हम उन क्षेत्रों के लिए #if / #ifdefined बिट्स का उपयोग करते हैं जिन्हें आप अतिरिक्त डिबगिंग चालू करना चाहते हैं ..
जॉन केज

5

#ifआपको कार्यक्षमता को बंद करने के लिए इसे 0 पर सेट करने का विकल्प देता है, जबकि अभी भी पता लगा रहा है कि स्विच है।
व्यक्तिगत रूप से मुझे हमेशा #define DEBUG 1ऐसा लगता है कि मैं इसे #if या #ifdef के साथ पकड़ सकता हूं


1
यह विफल हो जाता है, क्योंकि #define DEBUG = 0 अब #if नहीं चलेगा बल्कि
#ifdef

1
इस बिंदु पर, मैं या तो पूरी तरह से DEBUG को हटा सकता हूं या इसे अक्षम करने के लिए इसे 0 पर सेट कर सकता हूं।
मार्टिन बेकेट

यह होना चाहिए #define DEBUG 1। नहीं#define DEBUG=1
केशव जीएन

4

#if और # अल्पाइन MY_MACRO (0)

#If का उपयोग करने का अर्थ है कि आपने "परिभाषित" मैक्रो बनाया है, अर्थात, कुछ ऐसा जिसे कोड में खोजा जाएगा "(0)" द्वारा प्रतिस्थापित किया जाएगा। यह "मैक्रो नरक" है मुझे C ++ में देखने से नफरत है, क्योंकि यह संभावित कोड संशोधनों के साथ कोड को प्रदूषित करता है।

उदाहरण के लिए:

#define MY_MACRO (0)

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

जी ++ पर निम्नलिखित त्रुटि देता है:

main.cpp|408|error: lvalue required as left operand of assignment|
||=== Build finished: 1 errors, 0 warnings ===|

केवल एक त्रुटि।

जिसका अर्थ है कि आपके मैक्रो ने आपके C ++ कोड के साथ सफलतापूर्वक बातचीत की: फ़ंक्शन को कॉल सफल रहा। इस सरल मामले में, यह मनोरंजक है। लेकिन अपने कोड के साथ चुपचाप खेलने वाले मैक्रों के साथ मेरा खुद का अनुभव खुशी और फुलफिलमेंट से भरा नहीं है, इसलिए ...

#ifdef और #define MY_MACRO

#Ifdef का उपयोग करने का अर्थ है कि आप कुछ "परिभाषित" करते हैं। ऐसा नहीं है कि आप इसे एक मूल्य देते हैं। यह अभी भी प्रदूषित है, लेकिन कम से कम, यह "कुछ भी नहीं" द्वारा प्रतिस्थापित किया जाएगा, और सी + + कोड द्वारा लैगिट कोड स्टेटमेंट के रूप में नहीं देखा जाएगा। ऊपर एक ही कोड, एक साधारण परिभाषित के साथ, यह:

#define MY_MACRO

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

निम्नलिखित चेतावनियाँ देता है:

main.cpp||In function int main(int, char**)’:|
main.cpp|406|error: expected unqualified-id before ‘=’ token|
main.cpp|399|error: too few arguments to function int doSomething(int)’|
main.cpp|407|error: at this point in file|
||=== Build finished: 3 errors, 0 warnings ===|

इसलिए...

निष्कर्ष

मैं अपने कोड में मैक्रोज़ के बिना रहूंगा, लेकिन कई कारणों से (हेडर गार्ड या डिबग मैक्रोज़ को परिभाषित करते हुए), मैं नहीं कर सकता।

लेकिन कम से कम, मैं अपने वैध सी ++ कोड के साथ उन्हें कम से कम इंटरैक्टिव संभव बनाना पसंद करता हूं। जिसका अर्थ है बिना मूल्य के #define का उपयोग करना, #ifdef और #ifndef का उपयोग करना (या जिम बक द्वारा सुझाए गए # भी), और सबसे बढ़कर, उन्हें उनके इतने लंबे और इतने एलियन नाम देना उनके सही दिमाग का उपयोग नहीं करेगा यह "संयोग से" है, और यह किसी भी तरह से वैध सी ++ कोड को प्रभावित नहीं करेगा।

स्क्रिप्टम के बाद

अब, जैसा कि मैं अपनी पोस्ट को फिर से पढ़ रहा हूं, मुझे आश्चर्य है कि क्या मुझे कुछ मूल्य खोजने की कोशिश नहीं करनी चाहिए जो मेरे परिभाषित में जोड़ने के लिए कभी भी C ++ सही नहीं होंगे। कुछ इस तरह

#define MY_MACRO @@@@@@@@@@@@@@@@@@

जो #ifdef और #ifndef के साथ उपयोग किया जा सकता है, लेकिन किसी फ़ंक्शन के अंदर उपयोग किए जाने पर कोड संकलित नहीं होने दें ... मैंने इसे g ++ पर सफलतापूर्वक आज़माया, और इसने त्रुटि दी:

main.cpp|410|error: stray ‘@’ in program|

दिलचस्प। :-)


मैं सहमत हूं कि मैक्रोज़ खतरनाक हो सकते हैं, लेकिन यह पहला उदाहरण डिबग के लिए काफी स्पष्ट होगा और निश्चित रूप से यह केवल एक त्रुटि देता है। आप और अधिक की उम्मीद क्यों करेंगे? मैंने मैक्रों के परिणामस्वरूप बहुत नास्टियर त्रुटियां देखी हैं ...
जॉन केज

यह सच है कि एक समाधान और दूसरे के बीच का अंतर लगभग तुच्छ है। लेकिन इस मामले में, जैसा कि हम दो प्रतिस्पर्धी कोडिंग शैलियों के बारे में बात कर रहे हैं, तब भी तुच्छ को नजरअंदाज नहीं किया जा सकता है, क्योंकि उसके बाद, जो कुछ बचा है वह व्यक्तिगत स्वाद है (और उस बिंदु पर, मेरा मानना ​​है कि इसे सामान्य नहीं किया जाना चाहिए। )
पीरसीबल

4

यह शैली की बात नहीं है। साथ ही सवाल दुर्भाग्यपूर्ण है। आप बेहतर या सुरक्षित के अर्थ में इन प्रीप्रोसेसर निर्देशों की तुलना नहीं कर सकते।

#ifdef macro

का अर्थ है "यदि मैक्रो परिभाषित है" या "यदि मैक्रो मौजूद है"। यहाँ स्थूल का मूल्य मायने नहीं रखता। यह जो कुछ भी हो सकता है।

#if macro

यदि हमेशा एक मूल्य की तुलना करें। उपरोक्त उदाहरण में यह मानक अंतर्निहित तुलना है:

#if macro !=0

#if के उपयोग के लिए उदाहरण

#if CFLAG_EDITION == 0
    return EDITION_FREE;
#elif CFLAG_EDITION == 1
    return EDITION_BASIC;
#else
    return EDITION_PRO;
#endif

अब आप या तो CFLAG_EDITION की परिभाषा या तो अपने कोड में डाल सकते हैं

#define CFLAG_EDITION 1 

या आप संकलक ध्वज के रूप में मैक्रो सेट कर सकते हैं। इसके अलावा यहाँ देख


2

पहला मुझे स्पष्ट लगता है। ऐसा लगता है कि परिभाषित / परिभाषित न होने की तुलना में यह अधिक प्राकृतिक है।


2

दोनों बिल्कुल बराबर हैं। मुहावरेदार उपयोग में, #ifdef का उपयोग केवल परिभाषितता के लिए जाँच करने के लिए किया जाता है (और मैं आपके उदाहरण में क्या उपयोग करूँगा), जबकि #if का उपयोग अधिक जटिल अभिव्यक्तियों में किया जाता है, जैसे कि #if परिभाषित (A) &&! परिभाषित (B)।


1
ओपी यह नहीं पूछ रहा था कि "#ifdef" और "#if परिभाषित" के बीच क्या बेहतर है, बल्कि "# ifdef / # के बीच" और "#if" के बीच बेहतर है।
शंख

1

थोड़ा ओटी, लेकिन प्रीप्रोसेसर के साथ लॉगिंग चालू / बंद करना निश्चित रूप से सी ++ में उप-इष्टतम है। अपाचे के log4cxx जैसे अच्छे लॉगिंग टूल हैं जो ओपन-सोर्स हैं और प्रतिबंधित नहीं करते हैं कि आप अपने एप्लिकेशन को कैसे वितरित करते हैं। वे आपको पुनर्संयोजन के बिना भी लॉगिंग स्तर को बदलने की अनुमति देते हैं, यदि आप लॉगिंग बंद कर देते हैं, तो बहुत कम ओवरहेड होता है, और आपको उत्पादन में पूरी तरह से लॉगिंग को चालू करने का मौका देता है।


1
मैं सहमत हूं, और हम वास्तव में ऐसा करते हैं कि हमारे कोड में, मुझे सिर्फ एक चीज का उदाहरण चाहिए था जिसका उपयोग आप #if आदि के लिए कर सकते हैं
जॉन केज

1

मैं इस्तेमाल करता था #ifdef , लेकिन जब मैंने दस्तावेज़ीकरण के लिए Doxygen पर स्विच किया, तो मैंने पाया कि टिप्पणी-आउट मैक्रोज़ को प्रलेखित नहीं किया जा सकता है (या, कम से कम, Doxygen एक चेतावनी पैदा करता है)। इसका मतलब है कि मैं उस फीचर-स्विच मैक्रोज़ का दस्तावेज़ नहीं दे सकता जो वर्तमान में सक्षम नहीं हैं।

हालाँकि यह केवल डीऑक्सीजन के लिए मैक्रोज़ को परिभाषित करना संभव है, इसका मतलब है कि कोड के गैर-सक्रिय भागों में मैक्रोज़ को भी दस्तावेज किया जाएगा। मैं व्यक्तिगत रूप से फीचर स्विच दिखाना चाहता हूं और अन्यथा केवल वही दस्तावेज है जो वर्तमान में चुना गया है। इसके अलावा, यह कोड को काफी गड़बड़ कर देता है यदि कई मैक्रोज़ हैं जिन्हें केवल तभी परिभाषित किया जाना है जब Doxygen फ़ाइल को संसाधित करता है।

इसलिए, इस मामले में, हमेशा मैक्रोज़ को परिभाषित करना और उपयोग करना बेहतर होता है #if


0

मैंने इसे परिभाषित करने के लिए हमेशा #ifdef और संकलक झंडे का उपयोग किया है ...


कोई विशेष कारण (जिज्ञासा से बाहर)?
जॉन केज

2
सच कहूं तो मैंने इसके बारे में कभी नहीं सोचा था - बस यह हो गया है कि जिन जगहों पर मैंने काम किया है। यह लाभ यह है कि बजाय एक उत्पादन का निर्माण तुम सब करने की है के लिए एक कोड परिवर्तन करने की डिबग के लिए 'मेक डीबग', या 'मेक उत्पादन' नियमित के लिए है देता है
tloach

0

वैकल्पिक रूप से, आप एक वैश्विक स्थिरांक की घोषणा कर सकते हैं, और C ++ का उपयोग कर सकते हैं, यदि प्रीप्रोसेसर #if के बजाय। संकलक को आपके लिए अप्रयुक्त शाखाओं का अनुकूलन करना चाहिए, और आपका कोड क्लीनर होगा।

यहाँ स्टीफन सी। डेहर्स्ट द्वारा C ++ गोत्च्स को # if का उपयोग करने के बारे में कहा गया है।


1
यह एक घटिया समाधान है, इसमें निम्न समस्याएं हैं: 1. केवल कार्यों में काम करता है, आप अनावश्यक वर्ग चर को दूर नहीं कर सकते हैं, आदि 2. संकलक अप्राप्य कोड के बारे में चेतावनी फेंक सकते हैं 3. कोड यदि अभी भी संकलन करने की आवश्यकता है, जिसका अर्थ है आपको अपने सभी डिबग फ़ंक्शंस को परिभाषित रखना होगा, इत्यादि
डॉन नेफेल्ड

पहला सवाल विशेष रूप से डिबग प्रिंटफ के बारे में था, इसलिए अनावश्यक वर्ग चर यहां एक मुद्दा नहीं हैं। दूसरा, आधुनिक संकलक की क्षमताओं को देखते हुए आपको #ifdefs का कम से कम उपयोग करना चाहिए। ज्यादातर मामलों में आप इसके बजाय बिल्ड कॉन्फ़िगरेशन या टेम्पलेट विशेषज्ञताओं का उपयोग कर सकते हैं।
दिमा

0

ड्राइवर को सशर्त परिभाषित करने के लिए अलग-अलग तरीके के मामले में एक अंतर है:

diff <( echo | g++ -DA= -dM -E - ) <( echo | g++ -DA -dM -E - )

उत्पादन:

344c344
< #define A 
---
> #define A 1

इसका मतलब है, कि इसके -DAलिए पर्यायवाची है -DA=1और यदि मान छोड़ा जाता है, तो यह #if Aउपयोग के मामले में समस्याओं का कारण बन सकता है ।


0

मुझे पसंद है #define DEBUG_ENABLED (0)जब आप डिबग के कई स्तर चाहते हैं। उदाहरण के लिए:

#define DEBUG_RELEASE (0)
#define DEBUG_ERROR (1)
#define DEBUG_WARN (2)
#define DEBUG_MEM (3)
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL (DEBUG_RELEASE)
#endif
//...

//now not only
#if (DEBUG_LEVEL)
//...
#endif

//but also
#if (DEBUG_LEVEL >= DEBUG_MEM)
LOG("malloc'd %d bytes at %s:%d\n", size, __FILE__, __LINE__);
#endif

मेमोरी लीक्स को डिबग करना आसान बनाता है, अन्य चीजों को डीबग करने के आपके रास्ते में उन सभी लॉग लाइनों के बिना।

इसके अलावा #ifndefपरिभाषित के आसपास कमांडलाइन पर एक विशिष्ट डिबग स्तर चुनना आसान हो जाता है:

make -DDEBUG_LEVEL=2
cmake -DDEBUG_LEVEL=2
etc

यदि इसके लिए नहीं, तो मैं इसका लाभ दूंगा #ifdefक्योंकि फ़ाइल में कंपाइलर / मेक फ्लैग को ओवरराइड किया जाएगा। इसलिए आपको कमिट करने से पहले हेडर को बदलने के बारे में चिंता करने की ज़रूरत नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.