अगर-डायरेक्टिव मैक्रो तुलना


25

#ifनिम्नलिखित कोड में शर्त क्यों पूरी होती है:

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}

जवाबों:


26

Cppreference.com पर पेज कहता है:

परिभाषित और __has_include (C ++ 17 के बाद से) के सभी मैक्रो विस्तार और मूल्यांकन के बाद, कोई भी पहचानकर्ता जो बूलियन शाब्दिक नहीं है उसे नंबर 0 से बदल दिया जाता है (इसमें ऐसे पहचानकर्ता शामिल हैं जो शाब्दिक कीवर्ड हैं, लेकिन वैकल्पिक टोकन जैसे और )।

दोनों तो fooऔर bar0 से बदला जाता है।


C ++ 98, C ++ 03, C ++ 11 और C ++ 14 के बारे में क्या?
केलकाका

1
@kelalaka यह सब समान है। यह C89 के बाद से इस तरह से किया गया है।
एसएस ऐनी

1
@kelalaka "C ++ 17 के बाद से" केवल "और __has_include" भाग को संदर्भित करता है। C ++ 17 से पहले यह समान था, बस उस हिस्से को छोड़ दिया गया था।
बेसी.काउ

15

एक में #ifबयान, किसी भी पहचानकर्ता कि मैक्रो प्रतिस्थापन (के अलावा के बाद बनी हुई है trueऔर false) लगातार बदल दिए जाते हैं 0। तो आपका निर्देशन बन जाता है

#if 0 == 0

कौन सा सही है।


स्पष्ट करने के लिए, '#define VALUE foo' प्रतीक 'VALUE' को उसी मान के रूप में परिभाषित करता है जो प्रतीक 'foo' के समान है, लेकिन प्रतीक 'foo' का कोई अर्थ नहीं है, इसलिए इसे 0. के रूप में समझा जाएगा
ManicDee

13

इसका कारण यह है न fooहै और न ही barकिसी भी परिभाषा या मूल्य दिया गया है - तो वे ही कर रहे हैं (यानी एक "0" मान से बदल)। कंपाइलर्स इस बारे में चेतावनी देंगे।

MSVCसंकलक (विजुअल स्टूडियो -2019) निम्नलिखित देता है:

चेतावनी C4668: 'foo' को प्रीप्रोसेसर मैक्रो के रूप में परिभाषित नहीं किया गया है, '#' के लिए '#' के स्थान पर # if / #
एलिफ ' चेतावनी C4668:' बार 'को प्रीप्रोसेसर मैक्रो के रूप में परिभाषित नहीं किया गया है,' # 'के लिए' 0 'की जगह / # elif '

तो VALUEमूल्य '0' दिया गया है (डिफ़ॉल्ट के लिए foo) और barभी '0' है, इसलिए VALUE == bar"TRUE।" का मूल्यांकन करता है।

इसी तरह, clang-clनिम्नलिखित देता है:

चेतावनी: 'फू' को परिभाषित नहीं किया गया है, 0 [-वुंडिफ] का मूल्यांकन करता है
: चेतावनी: 'बार' परिभाषित नहीं है, 0 [-वूंडफ] का मूल्यांकन करता है


क्या चेतावनी अनिवार्य है या यह संकलक की एक विशेषता है?
केलकाका

1
@kelalaka मेरे ज्ञान का सबसे अच्छा करने के लिए, कोई संकलक 'चेतावनी' अनिवार्य हैं! MSVCऔर clang-clसंकलक के साथ भी , यह चेतावनी अक्षम की जा सकती है (या तो विशेष रूप से, या एक उपयुक्त चेतावनी 'स्तर' सेट करके)।
एड्रियन मोल

0

यह सुनिश्चित करने के लिए कि आप क्या कर रहे हैं, यह प्रयास करें:

#include <iostream>
#define DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

इस स्थिति में आप डिबगिंग कथनों को "परिभाषित" को "अपरिभाषित" में बदल कर बंद कर सकते हैं।

#include <iostream>
#undef DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

आप पा सकते हैं कि आपका संकलक आपको कोड के बाहर DEBUG को परिभाषित करने की अनुमति देता है, जिस बिंदु पर आप कोड को कम कर सकते हैं

#include <iostream>

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

और फिर कम्पाइलर को एक विकल्प जैसे -DDEBUG = 0 से आह्वान करें

स्टीव मैककोनेल में रक्षात्मक प्रोग्रामिंग के अध्याय को देखें, "कोड कम्प्लीट।"

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