क्या सशर्त संकलन के लिए शॉर्टकट के रूप में C / C ++ मैक्रोज़ का उपयोग एक अच्छा अभ्यास है?


13

मान लीजिए कि मैं अपने कोड में कई प्रकार के आउटपुट संदेश रखना चाहता हूं। उनमें से एक है DEBUG, जो केवल तब मुद्रित होता है, जब कोड को डिबग मोड में संकलित किया जाता है।

आमतौर पर मुझे कुछ लिखना होता है

#ifdef DEBUG
    std::cout << "Debug message" << std::endl;
#endif

जो कई जगहों पर उपयोग करने के लिए बहुत बोझिल और कष्टप्रद है।

क्या कोड स्निपेट के लिए मैक्रो को परिभाषित करना एक अच्छा अभ्यास है, इसलिए आप इसे इस तरह से उपयोग करेंगे?

MSG_DEBUG("Debug message")

या क्या कोई अन्य, अधिक सुरुचिपूर्ण तरीका है कि मैक्रोज़ के बिना इससे कैसे निपटें? मुझे C और C ++ दोनों में संभव समाधानों के बारे में दिलचस्पी है, क्योंकि मैं दोनों भाषाओं का विभिन्न परियोजनाओं में उपयोग कर रहा हूं।



यह इस सवाल से स्पष्ट नहीं है कि आप सिर्फ एक फ़ंक्शन में सशर्त कोड क्यों नहीं डालेंगे और इसे कॉल करें। क्या कुछ अन्य बाधाएँ हैं जो इसे रोकेंगी?
एलेक्स

@gnat आपके द्वारा उल्लिखित प्रश्न इतना व्यापक है, कि अधिकांश लोग इसे इस विषय से नहीं जोड़ेंगे, खासकर जब वे इंटरनेट पर इस विशिष्ट प्रश्न को देख रहे होंगे।
ईनोकू

3
आपके प्रश्न को c और c ++ दोनों के साथ टैग किया गया है , हालांकि, वे बहुत अलग भाषाएं हैं। क्या आप स्पष्ट कर सकते हैं कि आप किस बारे में बात कर रहे हैं? आपका उदाहरण C में पूरी तरह से ठीक होगा, लेकिन constexpr ifउदाहरण के लिए C ++ में बेहतर तरीके से लागू किया जा सकता है ।
जोर्ग डब्ल्यू मित्तग

1
एक तरफ, निदान के रूप में जाना चाहिए STDERR। इसके अलावा, यह क्यों नहीं निर्भर करता है NDEBUGजैसे assert()कि इसके बजाय निर्भर करता है? तब आप इसे ऐसे परिभाषित कर सकते हैं #define DEBUG_MSG(MSG) assert(std::cerr << MSG), जो स्ट्रीम-स्टेट का भी परीक्षण करता है।
डेडुप्लिकेटर

जवाबों:


19

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

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


13

यहां व्यक्तिगत प्राथमिकता का एक तत्व है, लेकिन C ++ में मैं हेडर फ़ाइल में ऐसा करना पसंद करता हूं:

#ifdef _DEBUG
    void DebugMessage(...);
#else
    inline void DebugMessage(...) {}
#endif

ताकि फ़ंक्शन रिलीज़ बिल्ड में इनबिल्ट हो जाए, लेकिन डीबग बिल्ड में एक उचित फ़ंक्शन है, ताकि आपके पास उचित प्रकार की जाँच, समझदार त्रुटि संदेश, आदि हो और आगे की कार्यक्षमता (शायद लॉगिंग?) जोड़ने की क्षमता हो।

जाहिर है, आपको ब्लॉक .cppमें फ़ाइल में फ़ंक्शन की संबंधित परिभाषा को भी एन्सेक्ट करना होगा #ifdef _DEBUG


लेकिन कॉल उपरि अभी भी यहाँ मौजूद है, है ना?
ईनोकू

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

@ ईनोकू नहीं, जैसा कि डेविड कहते हैं, यह आपके द्वारा उपयोग किए जाने वाले किसी भी संकलक द्वारा हटा दिया जाएगा।
जैक एडले

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


2

निश्चित रूप से, बस यह सुनिश्चित कर लें कि आप अपनी टीम द्वारा दिए गए कोड दिशानिर्देशों पर आगे नहीं बढ़ रहे हैं। सुनिश्चित करें कि सिस्टम में कोई अन्य कोड सामान्य स्थिति के माध्यम से समान कार्यक्षमता तक पहुंचने का प्रयास नहीं करता है।

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