_DEBUG बनाम NDEBUG


142

कोड के डिबग वर्गों को निर्दिष्ट करने के लिए किस प्रीप्रोसेसर को परिभाषित किया जाना चाहिए?

उपयोग #ifdef _DEBUGया #ifndef NDEBUGया यह करने के लिए एक बेहतर तरीका है, उदा #define MY_DEBUG?

मुझे लगता _DEBUGहै कि Visual Studio विशिष्ट है, क्या NDEBUG मानक है?

जवाबों:


113

_DEBUGजब आप /MTdया /MDdविकल्प निर्दिष्ट करते हैं तो दृश्य स्टूडियो परिभाषित करता है , NDEBUGमानक-सी अभिक्रियाओं को निष्क्रिय करता है। उपयुक्त होने पर उनका उपयोग करें, _DEBUGयदि आप चाहते हैं कि आपका डिबगिंग कोड MS CRT डिबगिंग तकनीकों केNDEBUG अनुरूप हो और यदि आप संगत होना चाहते हैंassert()

यदि आप अपने डिबगिंग मैक्रोज़ को परिभाषित करते हैं (और आप संकलक या सी रनटाइम को हैक नहीं करते हैं), तो अंडरस्कोर के साथ नाम शुरू करने से बचें, क्योंकि ये आरक्षित हैं।


19
+1। विशेष रूप से NDEBUG को एक एकल TU के भीतर # अपरिभाषित और # परिभाषित किया जा सकता है (और पुन: छोड़कर <assert.h> तदनुसार मुखर मैक्रो बदल जाता है)। क्योंकि यह अपेक्षित / वांछित से भिन्न है, इसलिए यह उत्तर कहता है कि "संकलन-चौड़ा" डीबग ध्वज को नियंत्रित करने के लिए किसी अन्य मैक्रो का उपयोग करना आम है।

1
जाहिर है, यह खुद संकलक है जो इन मैक्रो को परिभाषित करता है न कि विजुअल स्टूडियो (आईडीई)। इस उत्तर के लिए बहुत बहुत धन्यवाद!
निकल्स आर

विंडोज ड्राइवर किट 8.1 से एप्लिकेशन टेम्प्लेट का उपयोग करते समय NDEBUG को परिभाषित नहीं किया जाता है। इस स्थिति में, आपको _DEBUG पर निर्भर रहना पड़ सकता है।
नेवोसॉक

53

क्या NDEBUG मानक है?

हाँ यह C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014 मानकों के लिए अर्थ "नॉट डीबग" के साथ एक मानक मैक्रो है। _DEBUGमानकों में कोई मैक्रोज़ नहीं हैं।

सी ++ 2003 मानक "17.4.2.1 हेडर" मानक सी पर "पेज 326" पर पाठक को भेजें।

यह NDEBUG मानक C लाइब्रेरी के समान है।

C89 में (C प्रोग्रामर ने इस मानक को मानक C के रूप में कहा जाता है) "4.2 DIAGNOSTICS" खंड में यह कहा गया था

http://port70.net/~nsz/c/c89/c89-draft.html

यदि NDEBUG को स्रोत फ़ाइल में उस बिंदु पर एक स्थूल नाम के रूप में परिभाषित किया गया है जहां शामिल है, तो एस्टर मैक्रो को केवल उसी रूप में परिभाषित किया गया है

     #define assert(ignore) ((void)0)

यदि _DEBUGमैक्रोज़ के दृश्य स्टूडियो में देखें


50

मैं भरोसा करता हूं NDEBUG, क्योंकि यह एकमात्र ऐसा व्यवहार है जिसका व्यवहार संकलक और कार्यान्वयन में मानकीकृत है (मानक मुखर मैक्रो के लिए प्रलेखन देखें)। नकारात्मक तर्क एक छोटी पठनीयता गति है, लेकिन यह एक सामान्य मुहावरा है जिसे आप जल्दी से अपना सकते हैं।

कुछ पर भरोसा करने _DEBUGके लिए एक विशेष संकलक और पुस्तकालय कार्यान्वयन के कार्यान्वयन विवरण पर भरोसा करना होगा। अन्य संकलक समान सम्मेलन का चयन कर सकते हैं या नहीं भी कर सकते हैं।

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

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


1
#if !defined(NDEBUG)<- @HostileFork यह नहीं है कि आपका क्या मतलब है? #ifनहीं #ifdef?
बॉब स्टीन

1
@BusStein के माध्यम से सही की गई मूल टिप्पणी: "मैंने कुछ करने के लिए (थोड़ी) पठनीयता को कम किया है" स्पीडबम्प "यह है कि जब कोई नो-डिबग कंडीशन उपयोग के बारे में बात कर रहा हो #ifdef NDEBUG... लेकिन तब के साथ नकारात्मक तर्क पर विशेष ध्यान दें #if !defined(NDEBUG)। अन्यथा #ifndef NDEBUG" एन में पकड़ना थोड़ा कठिन है "
HostileFork का कहना है कि एसई

17

मैक्रो NDEBUGनियंत्रित करता है कि क्याassert() कथन सक्रिय हैं या नहीं।

मेरे विचार में, यह किसी भी अन्य डिबगिंग से अलग है - इसलिए मैं NDEBUGप्रोग्राम में डीबगिंग जानकारी को नियंत्रित करने के अलावा कुछ और का उपयोग करता हूं । मैं जो उपयोग करता हूं वह भिन्न होता है, उस रूपरेखा के आधार पर, जिसके साथ मैं काम कर रहा हूं; विभिन्न प्रणालियों में अलग-अलग सक्षम करने वाले मैक्रोज़ होते हैं, और मैं जो भी उपयुक्त होता है उसका उपयोग करता हूं।

यदि कोई ढांचा नहीं है, तो मैं एक प्रमुख अंडरस्कोर के बिना एक नाम का उपयोग करूंगा; उन लोगों को 'कार्यान्वयन' के लिए आरक्षित किया जाता है और मैं नाम के टकराव के साथ समस्याओं से बचने की कोशिश करता हूं - दोगुना इसलिए जब नाम एक मैक्रो है।


क्या आप बता सकते हैं कि आप अन्य प्रकार के डिबगिंग से अलग क्यों मानते हैं? आप किन परिदृश्यों में एक और नहीं चाहते हैं?
एड्रियन मैक्कार्थी

4
जब मैं कोड में अन्य डीबगिंग या ट्रेसिंग सुविधाओं को संकलित नहीं करता, तब भी मैं सक्रिय रहता हूं। दावे असंभव स्थितियों की पहचान करते हैं। सामान्य अनुरेखण और डिबगिंग IMO पूरी तरह से अलग है।
जोनाथन लेफ़लर

2
@AdrianMcCarthy: यदि आपके पास सभी डिबगिंग सक्षम है, तो यह प्रोग्रामों को धीरे-धीरे चलाने का कारण बन सकता है। इसलिए यह डिबगिंग के प्रकारों को वर्गीकृत करने के लिए आम है, और लोगों को उन्हें अलग से सक्षम / अक्षम करने की अनुमति देता है। MSVC में मानक पुस्तकालय के लिए विभिन्न डिबगिंग को सक्षम / अक्षम करने के लिए दो या तीन उपयोग होते हैं, जैसे std :: वेक्टर।
मूविंग डक

@MooDDuck: सहमत, लेकिन 'डिबगिंग उपलब्ध और सक्षम' और 'डीबगिंग उपलब्ध लेकिन अक्षम' और 'डीबगिंग उपलब्ध नहीं है' के बीच अंतर करें। उपलब्ध / उपलब्ध निर्णय एक संकलन समय मुद्दा (C या C ++ कोड में) है, और डिबगिंग उपलब्ध होने पर सक्षम / अक्षम तब रनटाइम निर्णय होता है। केवल crudest डीबगिंग सिस्टम 'उपलब्ध साधनों सक्षम' मोड के साथ काम करते हैं। (उस ने कहा, क्रूड प्रभावी हो सकता है, और क्रूड का एक बहुत कुछ है - लेकिन प्रभावी पर्याप्त - जंगली में डिबगिंग सिस्टम!)
जोनाथन लेफ़लर

2
@MooDDuck: हां, कुछ डिबगिंग कोड अलग-अलग हो सकते हैं। उस स्थिति में, आप यह नियंत्रित करने का एक तरीका चाहते हैं कि क्या धीमी कोड तुच्छ चेक से स्वतंत्र रूप से चलता है। लेकिन यह एक श्रेणी में अभिकथन और #ifदूसरे में -कंट्रोल कोड के समान नहीं है । assert(huge_object.IsValid());जबकि assert(ptr != nullptr);शायद नहीं है धीमा हो सकता है। मैं जोनाथन के साथ सहमत हूं कि लॉगिंग और ट्रेसिंग संभवतः कथनों से अलग होनी चाहिए, कम से कम बड़ी परियोजनाओं में, लेकिन मैं डिबग कोड के रूप में लॉगिंग या ट्रेसिंग के बारे में नहीं सोचता , यही कारण है कि मैंने स्पष्टीकरण के लिए कहा।
एड्रियन मैक्कार्थी

6

सुसंगत रहें और इससे कोई फर्क नहीं पड़ता कि कौन सा है। इसके अलावा यदि किसी कारण से आपको एक निश्चित डेबग पहचानकर्ता का उपयोग करके किसी अन्य प्रोग्राम या टूल के साथ इंटरॉप करना चाहिए तो यह करना आसान है

#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa

4

दुर्भाग्य DEBUGसे अत्यधिक भार है। उदाहरण के लिए, यह हमेशा बनाने और RELEASE बनाता है के लिए एक pdb फ़ाइल को बचाने के लिए सिफारिश की है। जिसका मतलब -Zxझंडे में से एक है , और -DEBUGलिंकर विकल्प। जबकि _DEBUGरनटाइम लाइब्रेरी के विशेष डिबग संस्करणों जैसे कि कॉल टू mallocऔर से संबंधित है free। फिर NDEBUGदावे को अक्षम कर देगा।

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