C ++ पहचानकर्ता में अंडरस्कोर का उपयोग करने के बारे में क्या नियम हैं?
स्थानीय चर या मापदंडों के बजाय, इस तथ्य को निरूपित करने के लिए कि किसी प्रकार के उपसर्ग के साथ सदस्य चर का नाम देना C ++ में आम है। यदि आप MFC बैकग्राउंड से आते हैं, तो आप शायद इस्तेमाल करेंगे m_foo
। मैंने भी myFoo
कभी-कभी देखा है ।
C # (या संभवतः सिर्फ .NET) लगता है कि सिर्फ एक अंडरस्कोर का उपयोग करने की अनुशंसा करता है _foo
। क्या यह C ++ मानक द्वारा अनुमत है?
जवाब
नियम (जो C ++ 11 में नहीं बदले):
- कार्यान्वयन मैक्रो के रूप में उपयोग के लिए सहित किसी भी दायरे में आरक्षित :
- एक अपरकेस के साथ शुरुआत करने वाले पहचानकर्ता तुरंत एक बड़े अक्षर के बाद
- समीपवर्ती अंडरस्कोर (या "डबल अंडरस्कोर") वाले पहचानकर्ता
- वैश्विक नाम स्थान में आरक्षित:
- एक अंडरस्कोर के साथ शुरुआत करने वाले पहचानकर्ता
- इसके अलावा,
std
नाम स्थान में सब कुछ आरक्षित है। (आपको खाका विशेषज्ञता जोड़ने की अनुमति है, हालांकि)
2003 C ++ मानक से:
17.4.3.1.2 वैश्विक नाम [lib.global.names]
नाम और फ़ंक्शन हस्ताक्षर के कुछ सेट हमेशा कार्यान्वयन के लिए आरक्षित होते हैं:
- प्रत्येक नाम जिसमें एक डबल अंडरस्कोर (
__
) है या एक अपरकेस अक्षर से शुरू होता है (2.11) किसी भी उपयोग के लिए कार्यान्वयन के लिए आरक्षित है।- अंडरस्कोर से शुरू होने वाला प्रत्येक नाम वैश्विक नामस्थान में एक नाम के रूप में उपयोग के लिए कार्यान्वयन के लिए आरक्षित है। 165
165) ऐसे नाम नामस्थान
::std
(17.4.3.1) में भी आरक्षित हैं ।
क्योंकि C ++ C मानक (1.1 / 2, C ++ 03) पर आधारित है और C99 एक मानक संदर्भ (1.2 / 1, C ++ 03) है, ये भी 1999 सी मानक से लागू होते हैं:
7.1.3 आरक्षित पहचानकर्ता
प्रत्येक हेडर अपने संबंधित उप-धारा में सूचीबद्ध सभी पहचानकर्ताओं को घोषित करता है या परिभाषित करता है, और अपने संबंधित भविष्य के पुस्तकालय दिशा-निर्देशों उप-सूची और पहचानकर्ताओं में सूचीबद्ध पहचानकर्ताओं को वैकल्पिक रूप से घोषित करता है या परिभाषित करता है जो हमेशा किसी भी उपयोग के लिए या फ़ाइल गुंजाइश पहचानकर्ता के रूप में उपयोग के लिए आरक्षित होते हैं।
- सभी पहचानकर्ता जो एक अंडरस्कोर से शुरू होते हैं और या तो एक बड़े अक्षर या किसी अन्य अंडरस्कोर को हमेशा किसी भी उपयोग के लिए आरक्षित किया जाता है।
- सभी पहचानकर्ता जो एक अंडरस्कोर से शुरू होते हैं, हमेशा साधारण और टैग नाम रिक्त स्थान दोनों में फ़ाइल स्कोप वाले पहचानकर्ताओं के रूप में उपयोग के लिए आरक्षित होते हैं।
- निम्न उपवर्गों में से प्रत्येक में एक स्थूल नाम (भविष्य की लाइब्रेरी दिशाओं सहित) निर्दिष्ट करने के लिए उपयोग के लिए आरक्षित है यदि इसके किसी भी संबंधित हेडर को शामिल किया गया है; जब तक स्पष्ट रूप से अन्यथा न कहा जाए (देखें 7.1.4)।
- निम्नलिखित उपवर्गों में से किसी में बाहरी लिंकेज वाले सभी पहचानकर्ता (भविष्य की लाइब्रेरी दिशाओं सहित) हमेशा बाहरी लिंकेज वाले पहचानकर्ताओं के रूप में उपयोग के लिए आरक्षित होते हैं। 154
- निम्न उपवर्गों में से किसी में सूचीबद्ध फ़ाइल स्कोप वाले प्रत्येक पहचानकर्ता (भविष्य की लाइब्रेरी दिशाओं सहित) को मैक्रो नाम के रूप में उपयोग करने के लिए आरक्षित किया गया है और यदि किसी भी संबंधित हेडर को शामिल किया गया है तो उसी नाम के स्थान पर फ़ाइल स्कोप के साथ एक पहचानकर्ता है।
कोई अन्य पहचानकर्ता आरक्षित नहीं है। यदि कार्यक्रम एक ऐसे संदर्भ में पहचानकर्ता की घोषणा या परिभाषित करता है, जिसमें यह आरक्षित है (7.1.4 द्वारा अनुमत के अलावा), या मैक्रो नाम के रूप में आरक्षित पहचानकर्ता को परिभाषित करता है, तो व्यवहार अपरिभाषित है।
यदि प्रोग्राम
#undef
ऊपर सूचीबद्ध पहले समूह में एक पहचानकर्ता की किसी भी स्थूल परिभाषा को हटा देता है (के साथ ), व्यवहार अपरिभाषित है।154) बाहरी लिंकेज के साथ सुरक्षित पहचानकर्ता के सूची में शामिल हैं
errno
,math_errhandling
,setjmp
, औरva_end
।
अन्य प्रतिबंध लागू हो सकते हैं। उदाहरण के लिए, POSIX मानक में बहुत सारे पहचानकर्ता होते हैं जो सामान्य कोड में दिखाई देते हैं:
- एक राजधानी से शुरू होने वाले नामों
E
ने एक अंक या बड़े अक्षर का अनुसरण किया:- अतिरिक्त त्रुटि कोड नामों के लिए उपयोग किया जा सकता है।
- नाम जो
is
या तोto
लोअरकेस अक्षर से शुरू होते हैं- अतिरिक्त चरित्र परीक्षण और रूपांतरण कार्यों के लिए उपयोग किया जा सकता है।
- नाम जो
LC_
एक बड़े अक्षर से शुरू होते हैं- स्थानीय विशेषताओं को निर्दिष्ट करने वाले अतिरिक्त मैक्रो के लिए उपयोग किया जा सकता है।
- सभी मौजूदा गणित कार्यों के नाम के साथ प्रत्यय
f
याl
आरक्षित हैं- इसी तरह के कार्यों के लिए जो क्रमशः फ्लोट और लंबे डबल तर्कों पर काम करते हैं।
SIG
एक बड़े अक्षर से शुरू होने वाले नाम आरक्षित हैं- अतिरिक्त संकेत नामों के लिए।
SIG_
एक बड़े अक्षर से शुरू होने वाले नाम आरक्षित हैं- अतिरिक्त सिग्नल कार्यों के लिए।
- के साथ शुरुआत नाम
str
,mem
याwcs
एक छोटा अक्षर के बाद आरक्षित हैं- अतिरिक्त स्ट्रिंग और सरणी फ़ंक्शन के लिए।
- किसी भी लोअरकेस अक्षर के साथ
PRI
याSCN
उसके बाद शुरू होने वाले नाम याX
आरक्षित हैं- अतिरिक्त प्रारूप निर्दिष्ट मैक्रोज़ के लिए
- जो नाम समाप्त होते
_t
हैं, वे आरक्षित होते हैं- अतिरिक्त प्रकार के नामों के लिए।
अपने स्वयं के प्रयोजनों के लिए इन नामों का उपयोग करते समय अभी समस्या उत्पन्न नहीं हो सकती है, वे उस मानक के भविष्य के संस्करणों के साथ संघर्ष की संभावना को बढ़ाते हैं।
व्यक्तिगत रूप से मैं सिर्फ अंडरस्कोर वाले पहचानकर्ताओं को शुरू नहीं करता हूं। मेरे नियम के अलावा नया: कहीं भी डबल अंडरस्कोर का उपयोग न करें, जो आसान है क्योंकि मैं शायद ही कभी अंडरस्कोर का उपयोग करता हूं।
इस लेख पर शोध करने के बाद मैं अपने पहचानकर्ताओं को समाप्त नहीं करता _t
क्योंकि यह POSIX मानक द्वारा आरक्षित है।
किसी भी पहचानकर्ता के समाप्त होने के बारे में नियम ने _t
मुझे बहुत आश्चर्यचकित किया। मुझे लगता है कि स्पष्टीकरण और आधिकारिक अध्याय और पद्य की तलाश में यह एक POSIX मानक है (अभी तक निश्चित नहीं है)। यह GNU libtool मैनुअल से है , आरक्षित नामों को सूचीबद्ध करता है।
CesarB ने POSIX 2004 आरक्षित प्रतीकों और नोटों के लिए निम्न लिंक प्रदान किया है 'कि कई अन्य आरक्षित उपसर्ग और प्रत्यय ... वहाँ पाए जा सकते हैं'। POSIX 2008 सुरक्षित प्रतीकों यहाँ परिभाषित कर रहे हैं। प्रतिबंध कुछ हद तक ऊपर की तुलना में अति सूक्ष्म हैं।
नामों की टकराहट से बचने के नियम C ++ मानक (Stroustrup पुस्तक देखें) और C ++ गुरु (सटर, आदि) द्वारा उल्लिखित दोनों हैं।
व्यक्तिगत नियम
क्योंकि मैं मामलों से निपटना नहीं चाहता था, और एक सरल नियम चाहता था, मैंने एक व्यक्तिगत डिजाइन किया है जो सरल और सही दोनों है:
जब एक प्रतीक का नामकरण, आप संकलक / ओएस / मानक पुस्तकालयों के साथ टकराव से बचेंगे यदि आप:
- एक अंडरस्कोर के साथ एक प्रतीक को कभी भी शुरू न करें
- कभी भी अंदर के दो अंडरस्कोर वाले सिंबल का नाम न लें।
बेशक, अपने कोड को एक अद्वितीय नामस्थान में रखने से टकराव से बचने में मदद मिलती है, (लेकिन यह बुरे मैक्रोज़ से रक्षा नहीं करेगा)
कुछ उदाहरण
(मैं मैक्रोज़ का उपयोग करता हूं क्योंकि वे C / C ++ प्रतीकों के अधिक कोड-प्रदूषण हैं, लेकिन यह चर नाम से लेकर कक्षा तक कुछ भी हो सकता है)
#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT
C ++ 0x ड्राफ्ट से अर्क
से n3242.pdf फ़ाइल (मैं समान होने के लिए अंतिम मानक पाठ की उम्मीद):
17.6.3.3.2 वैश्विक नाम [Global.names]
नाम और फ़ंक्शन हस्ताक्षर के कुछ सेट हमेशा कार्यान्वयन के लिए आरक्षित होते हैं:
- प्रत्येक नाम जिसमें एक डबल अंडरस्कोर _ _ है या एक अंडरस्कोर के साथ शुरू होता है उसके बाद एक अपरकेस अक्षर (2.12) किसी भी उपयोग के लिए कार्यान्वयन के लिए आरक्षित है।
- अंडरस्कोर से शुरू होने वाला प्रत्येक नाम वैश्विक नामस्थान में एक नाम के रूप में उपयोग के लिए कार्यान्वयन के लिए आरक्षित है।
लेकिन:
17.6.3.3.5 उपयोगकर्ता द्वारा परिभाषित शाब्दिक प्रत्यय [usrlit.suffix]
शाब्दिक प्रत्यय पहचानकर्ता जो अंडरस्कोर से शुरू नहीं होते हैं, भविष्य के मानकीकरण के लिए आरक्षित हैं।
यह अंतिम खंड भ्रमित करने वाला है, जब तक आप विचार नहीं करते हैं कि एक नाम एक अंडरस्कोर से शुरू होता है और उसके बाद एक लोअरकेस अक्षर ठीक होता है यदि वैश्विक नामस्थान में परिभाषित नहीं किया गया है ...
से MSDN :
एक पहचानकर्ता की शुरुआत में दो अनुक्रमिक अंडरस्कोर वर्ण (__) का उपयोग, या एक प्रमुख अक्षर के बाद एक एकल प्रमुख अंडरस्कोर, सभी स्कैप में C ++ कार्यान्वयन के लिए आरक्षित है। आपको वर्तमान या भविष्य के अन्य पहचानकर्ताओं के साथ संभावित संघर्षों के कारण फ़ाइल स्कोप वाले नामों के लिए एक निचले अक्षर के बाद एक प्रमुख अंडरस्कोर का उपयोग करने से बचना चाहिए।
इसका मतलब है कि आप एक एकल अंडरस्कोर का उपयोग एक सदस्य चर उपसर्ग के रूप में कर सकते हैं, जब तक कि यह एक निम्न-केस पत्र द्वारा पीछा किया जाता है।
यह जाहिरा तौर पर C ++ मानक के खंड 17.4.3.1.2 से लिया गया है, लेकिन मुझे पूर्ण मानक ऑनलाइन के लिए एक मूल स्रोत नहीं मिल सकता है।
यह प्रश्न भी देखें ।
प्रश्न के अन्य भाग के रूप में, यह कुछ भी आंतरिक के साथ संघर्ष नहीं करने के लिए चर नाम के अंत में अंडरस्कोर डालना आम है ।
मैं कक्षाओं और नामस्थानों के अंदर भी ऐसा करता हूं क्योंकि मुझे केवल एक नियम याद रखना पड़ता है (वैश्विक दायरे में नाम के अंत में और हर जगह नाम की शुरुआत की तुलना में)।
हाँ, पहचानकर्ता में कहीं भी अंडरस्कोर का उपयोग किया जा सकता है। मेरा मानना है कि नियम हैं: पहले अक्षर में कोई भी, AZ, _ और निम्न वर्णों के लिए + 0-9।
सी कोड में अंडरस्कोर उपसर्ग आम हैं - एक एकल अंडरस्कोर का अर्थ "निजी" है, और डबल अंडरस्कोर आमतौर पर कंपाइलर द्वारा उपयोग के लिए आरक्षित हैं।