2012-03-01 11 views
8
#include <iostream> 
#define true false 
#define false true 
int main() { 
    std::cout << false << true; 
} 

यह "01" क्यों आउटपुट करता है?झूठी और इसके विपरीत सच को फिर से परिभाषित करते समय अपेक्षित आउटपुट क्या होता है?

+23

गंभीरता से? आपने वह कोड लिखा है? 'सत्य' को 'झूठी' में परिभाषित करने के लिए और इसके विपरीत? निकटतम जूता ढूंढें और जब तक आप यह समझ न लें कि समस्या क्या है, तब तक बार-बार सिर पर खुद को हराएं। –

+1

मैंने इस कोड को नहीं लिखा है (= मैं सिर्फ – hired777

+2

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

उत्तर

13

जेरी कॉफ़िन नोट्स के रूप में, आप एक मैक्रो को एक ऐसे नाम के साथ परिभाषित नहीं कर सकते जो एक कीवर्ड है।

हालांकि, हम एक और समान उदाहरण, अच्छी तरह से परिभाषित व्यवहार और एक ही परिणाम के साथ विचार कर सकते हैं। पर विचार करें:

int TRUE = 1; 
int FALSE = 0; 

#define TRUE FALSE 
#define FALSE TRUE 

std::cout << FALSE << TRUE; 

आप FALSE उपयोग करते हैं, यह मैक्रो FALSE के रूप में पहचान की है और कहा कि मैक्रो की जगह सूची है, जो एक टोकन है, TRUE ने ले ली है। उस प्रतिस्थापन को प्रतिस्थापित करने के लिए आगे मैक्रोज़ के लिए बचाया गया है।

प्रतिस्थापन में TRUE को मैक्रो के रूप में पहचाना जाता है और इसकी प्रतिस्थापन सूची द्वारा प्रतिस्थापित किया जाता है, जो एकल टोकन FALSE है। वह प्रतिस्थापन फिर से बचाया गया है।

अगर हम rescanning और प्रतिस्थापन पर जारी रहे, तो हम एक अनंत लूप में समाप्त हो जाएंगे, इसलिए सी (और सी ++) प्रीप्रोकैसिंग विनिर्देश बताते हैं कि मैक्रो प्रतिस्थापन कभी प्रतिस्थापन सूची में नहीं आता है।

इस अंतिम प्रतिस्थापन सूची प्रत्यावर्तन में परिणाम होगा में FALSE के प्रतिस्थापन के बाद से, मैक्रो प्रतिस्थापन बंद हो जाता है और हम FALSE, जो 0 के एक मूल्य के साथ एक int का नाम है के साथ छोड़ दिया जाता है।

+0

अच्छी व्याख्या! लेकिन सिर्फ एक सवाल है, क्या आप उसे उपरोक्त जैसे कोड लिखने के लिए विचार दे रहे हैं ???? – noMAD

+0

उसने इसे नहीं लिखा था। –

+5

@noMAD: नहीं, किसी को सामान्य रूप से इस तरह कोड नहीं लिखना चाहिए, लेकिन इसका मतलब यह नहीं है कि हमें यह बताने की ज़रूरत नहीं है कि यह कोड इस तरह से क्यों काम करता है। यह समझना महत्वपूर्ण है कि आपकी प्रोग्रामिंग भाषा कैसे काम करती है, यहां तक ​​कि "कोई भी उपयोग नहीं करता" भाषा के "मूर्ख" कोनों में भी। रिकॉर्ड के लिए, मैंने सी प्रीप्रोसेसर के कार्यान्वयन के लिए यूनिट टेस्ट में इस तरह कोड लिखा है, मैं थोड़ी देर के लिए काम कर रहा था (माना जाता है कि मेरे पास अजीब शौक हैं)। –

11

आरक्षित शब्द को फिर से परिभाषित करने का कोई भी प्रयास अपरिभाषित व्यवहार देता है।

संपादित करें:

§2.11/1: "। तालिका 3 में दिखाया गया पहचानकर्ता कीवर्ड के रूप में उपयोग के लिए आरक्षित कर रहे हैं" मैं सभी तालिका 3 को पुन: उत्पन्न करने की कोशिश नहीं करूंगा, लेकिन इसमें झूठी और सत्य दोनों शामिल हैं। यह कुछ प्रश्नों के लिए खुला हो सकता है कि यह एक पूर्ण निषेध है, हालांकि, एक ही वाक्य में कहा गया है: "(यानी, उन्हें बिना शर्त रूप से चरण 7 में कीवर्ड के रूप में माना जाता है), जो बताता है कि कीवर्ड को फिर से परिभाषित करना संभव है रास्ता, चूंकि इसमें शामिल मैक्रोज़ चरण 7 से पहले विस्तारित किए जाएंगे।

इस मामले में, आपने <iostream> भी शामिल किया है, जो एक और नियम खेलता है (§17.4.3.1.1): "एक अनुवाद इकाई जिसमें हेडर शामिल है, में कोई भी मैक्रोज़ नहीं होगा जो उस शीर्षलेख में घोषित या परिभाषित नाम परिभाषित करता है। न ही ऐसी अनुवाद इकाई कीवर्ड के लिए समान रूप से समान नामों के लिए मैक्रोज़ को परिभाषित करेगी। "

यहां शब्द यह दृढ़ता से सुझाव देता है कि यदि कोई अनुवाद इकाई में कोई शीर्षलेख शामिल नहीं होता है, तो यह आपके द्वारा किए गए कीवर्ड को फिर से परिभाषित करने के लिए स्वतंत्र होगा, लेकिन #include <iostream> की उपस्थिति को देखते हुए, कोई सवाल नहीं है कि आपके पास अपरिभाषित व्यवहार है।

एक बार जब आप व्यवहार को अपरिभाषित कर लेते हैं, तो वास्तव में "क्यों" कुछ भी नहीं होता है - उस समय, मानक बहुत स्पष्ट है कि किसी भी व्यवहार की अनुमति है।

+0

प्लज़, आईएसओ – hired777

+1

से लिंक क्यों करें आप इसे "लिंक" के बजाय आईएसओ के माध्यम से क्यों नहीं देखते हैं? वैसे भी, "आईएसओ से लिंक" दस्तावेज़ के लिंक, इसलिए यह आपको कुछ भी नया नहीं देगा। – Griwes

+0

मैं इसके माध्यम से देखता हूं, लेकिन मुझे स्पष्टीकरण नहीं मिल रहा है – hired777