2012-02-02 17 views
10

सप्ताह के गुरु से this article में, यह कहा जाता है: It is illegal to #define a reserved word. क्या यह सच है? मुझे मानक में कुछ भी नहीं मिला है, और उदाहरण के लिए, मैंने प्रोग्रामर को नए को फिर से परिभाषित किया है।क्या सी ++ कीवर्ड को फिर से परिभाषित करना कानूनी है?

+1

आरक्षित शब्दों के अर्थों को बदलने के लिए 'परिभाषित' का उपयोग करना निश्चित रूप से संभव है। असल में इसका उपयोग अक्सर [अंतर्राष्ट्रीय Obfuscated सी कोड प्रतियोगिता] (http://www.ioccc.org/) प्रविष्टियों में किया जाता है। यह संभव है क्योंकि वास्तविक सी संकलक चलाने से पहले '# परिभाषित' द्वारा परिभाषित मैक्रोज़ को एक अलग प्रोग्राम द्वारा प्रतिस्थापित किया जाता है। –

+0

यकीन है कि उन्होंने नए ऑपरेटर को अधिभारित नहीं किया है? चूंकि प्रीप्रोसेसर पहले समस्या को फिर से चलाता है - "# परिभाषित" -जिंग कीवर्ड यह है कि आप अपनी प्रतिस्थापन स्ट्रिंग वाले कीवर्ड बदलते हैं, कोड यह अपेक्षा नहीं करता कि इसके बाद वहां सबसे अधिक टूटा जाएगा। ऐसा करने के लिए आम तौर पर एक बुरा विचार है, आप वैसे भी ऐसा क्यों करना चाहते हैं? – ted

+0

@ted: विचार एक स्रोत फ़ाइल में नए कीवर्ड को फिर से परिभाषित करना है ताकि प्लेटफ़ॉर्म-विशिष्ट कार्यान्वयन को कॉल किया जा सके: Macintosh पर '# new newMac' परिभाषित करें और '# नया नया पीसी' डिस्प्ले करें। अन्य अनुवाद इकाइयों में, संबंधित फ़ंक्शन प्लेटफ़ॉर्म-विशिष्ट मेमोरी आवंटकों को परिभाषित करेंगे। मुझे लगता है कि प्लेटफार्म-विशिष्ट व्यवहार करते समय हर जगह 'नया' इस्तेमाल करना जारी रखना था जब प्रत्येक कॉल को नए नाम का नाम बदलना संभव नहीं था। – qdii

उत्तर

18

17.4.3.1.1 मैक्रो नाम [lib.macro.names]

1 Each name defined as a macro in a header is reserved to the implementation for any use if the translation unit includes the header.164)
2 A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.

वैसे, new संचालक हो और यह अपने आप ही उपलब्ध कराने के द्वारा अतिभारित किया जा सकता (प्रतिस्थापित) उपयोगकर्ता द्वारा संस्करण।

+6

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

+1

तो मुझे तब तक 'नया परिभाषित करने की अनुमति है जब तक कि मेरी अनुवाद इकाई में कोई शीर्षलेख शामिल न हो: पी? @JamesKanze: क्यों ** मानक ** शीर्षलेख? – qdii

+0

@victor: मानक (टेम्पलेट) पुस्तकालय ?? – ted

-1

यह जहाँ तक मुझे पता है अवैध हूँ नहीं है - कोई संकलक मैं भर में अभी तक आए हैं एक त्रुटि उत्पन्न होगा यदि आप

#define true false 

#defining कोई कीवर्ड बहुत अन्य कारणों के लिए संकलन में त्रुटियों उत्पन्न होने की संभावना है कर । लेकिन उनमें से बहुत से परिणामस्वरूप बहुत अजीब कार्यक्रम व्यवहार होगा।

+0

ऐसी परिभाषा मानक पुस्तकालय के साथ समस्याएं पैदा करने की संभावना है। –

+0

संभवतः, कुछ हिस्सों पर। मेरी समस्या यह है कि यद्यपि यह अवैध है, हालांकि कंपाइलर को निदान जारी करने की कोई आवश्यकता नहीं प्रतीत होती है। और आपके द्वारा उपयोग की जाने वाली मानक लाइब्रेरी के किन बिट्स और जहां आपने इसे # कोड में परिभाषित किया है, इस पर निर्भर करता है, प्रोग्राम ठीक संकलित कर सकता है। –

+2

इतनी सारी चीजों की तरह, यह अपरिभाषित व्यवहार है। किसी कंपाइलर को इसका पता लगाने में मुश्किल नहीं होगी, और एक संकलन समय त्रुटि का कारण बनता है, लेकिन मुझे ऐसा करने के बारे में पता नहीं है। –

11

से सी ++ 11 इसी अनुभाग:

17.6.4.3.1 सी ++ 03 से मैक्रो नाम [macro.names]

1 A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.
2 A translation unit shall not #define or #undef names lexically identical to keywords.

अनुच्छेद 1 हटा दिया गया है। दूसरा अनुच्छेद दो में विभाजित किया गया है। पहली छमाही अब विशेष रूप से राज्य में बदल दी गई है कि यह केवल मानक हेडर पर लागू होती है। दूसरे बिंदु को किसी भी अनुवाद इकाई को शामिल करने के लिए विस्तृत किया गया है, न कि केवल हेडर शामिल हैं।

हालांकि, अवलोकन मानक (17.6.4.1 [constraints.overview]) के इस भाग के लिए कहा गया है:

This section describes restrictions on C++ programs that use the facilities of the C++ standard library.

इसलिए, यदि आप सी ++ मानक पुस्तकालय का उपयोग नहीं कर रहे हैं, तो आप जो करना चाहते हैं वह करने के लिए ठीक है।

तो सी ++ 11 के संदर्भ में अपने प्रश्न का उत्तर देने के लिए: यदि आप सी ++ मानक पुस्तकालय का उपयोग कर रहे हैं तो आप किसी भी अनुवाद इकाई में कीवर्ड के समान किसी भी नाम को परिभाषित नहीं कर सकते (या परिभाषित नहीं कर सकते)।

+0

+1 पर ध्यान नहीं दिया: आनंद – qdii

1

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

#define goto { int x = *(int *)0; } goto 

अब जब भी वह गोटो स्टेटमेंट का उपयोग करने का प्रयास करता है, तो उसका प्रोग्राम क्रैश हो जाएगा।

+0

upvoted है, लेकिन आप अपने आप को कहा है कि क्या यह हास्यास्पद बना देता है? जवाब यह है कि मनुष्य दुःखद प्राणी हैं और यह डरावना हिस्सा है ... मानव प्रकृति को इंगित करने के लिए +1। –

+0

@JackAidley हाँ के लिए दिलचस्प – doc

+4

यह एक अनिर्धारित व्यवहार है और इससे बचने के लिए सबसे अच्छा है। – Abhijit

2

वे वास्तव में गलत हैं, या कम से कम इस बारे में पूरी कहानी नहीं बताते हैं। वास्तविक कारण यह अस्वीकृत है कि यह एक परिभाषा-नियम का उल्लंघन करता है (जिस तरह से दूसरे कारण के रूप में भी इसका उल्लेख किया गया है कि यह अवैध क्यों है)।

यह देखने के लिए कि वास्तव में यह अनुमति है (कीवर्ड को फिर से परिभाषित करने के लिए), कम से कम यदि आप मानक पुस्तकालयों का उपयोग नहीं करते हैं, तो आपको मानक चरणों, अर्थात् अनुवाद चरणों का एक पूरी तरह से अलग हिस्सा देखना होगा। यह कहता है कि इनपुट प्रीप्रोसेसिंग होने से पहले प्रीप्रोसेसर टोकन में ही विघटित होता है और उन पर देखकर private और fubar के बीच कोई अंतर नहीं है, वे प्रीप्रोसेसर दोनों identifiers हैं।बाद में जब इनपुट token में विघटित हो गया है तो प्रतिस्थापन पहले ही हो चुका है।

यह मुद्दा उठाया गया प्रोग्राम हैं जो मानक पुस्तकालयों का उपयोग करने के लिए कर रहे हैं पर एक प्रतिबंध यह है कि है, लेकिन यह स्पष्ट नहीं है कि उदाहरण के फिर से परिभाषित करने private कि क्या कर रहा है (के रूप में "व्यक्ति # 4: भाषा वकील" के लिए विरोध का टुकड़ा जो इसे आउटपुट के लिए cout पर उपयोग करता है)।

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

संबंधित मुद्दे