c++ यदि कोई एनम एक अहस्ताक्षरित अभिन्न प्रकार में फिट नहीं हो सकता है तो क्या होगा?



types enums (1)

Bathsheba द्वारा अनुरोध के रूप में और एक अनुवर्ती प्रश्न के रूप में "क्या होता है अगर एक एनम एक अभिन्न प्रकार में फिट नहीं हो सकता है?" :

मान लें कि एनम को परिभाषित किया गया है:

enum foo : unsigned int
{
    bar = UINT_MAX,
    oops
};

क्या oops का मूल्य परिभाषित है या नहीं है?

MSVS2015 संकलन:

warning C4340: 'oops': value wrapped from positive to negative value
warning C4309: 'initializing': truncation of constant value
warning C4369: 'oops':  enumerator value '4294967296' cannot be represented as 'unsigned int', value is '0'

MSVS2015 आउटपुट:

bar = 4294967295
oops= 0

gcc 4.9.2 संकलन:

9 : note: in expansion of macro 'UINT_MAX'
bar = UINT_MAX,
^
10 : error: enumerator value 4294967296l is outside the range of underlying type 'unsigned int'
oops
^
Compilation failed

gcc 4.9.2 आउटपुट

//compilation failed

यह एक बहुत ही दिलचस्प सवाल है। सरल उत्तर यह है कि यह वस्तुतः अपरिभाषित है: मानक इस मामले के बारे में कुछ नहीं कहता है।

एक बेहतर उदाहरण के लिए, इस पर विचार करें:

 enum foo : bool { True=true, undefined };

मानक के अनुसार:

[ dcl.enum ] / 2 : [...] एक आरंभिक के बिना एक एन्यूमरेटर-परिभाषा एन्यूमरेटर को पिछले एन्यूमरेटर के मूल्य को एक से बढ़ाकर प्राप्त मान देता है।

इसलिए, हमारे उदाहरण में foo::undefined का मान 2 ( true+1 )। जिसे एक bool रूप में प्रस्तुत नहीं किया जा सकता है।

क्या यह बीमार है?

नहीं , मानक के अनुसार, यह पूरी तरह से वैध है, केवल निश्चित-निश्चित अंतर्निहित प्रकार में सभी प्रतिमान मूल्यों का प्रतिनिधित्व करने में सक्षम नहीं होने के बारे में प्रतिबंध है:

[ dcl.enum ] / 7 : एक गणना के लिए जिसका अंतर्निहित प्रकार तय नहीं है, [...] यदि कोई अभिन्न प्रकार सभी एन्यूमरेटर मूल्यों का प्रतिनिधित्व नहीं कर सकता है, तो एन्यूमरेशन बीमार है।

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

मूल प्रश्न के oops और undefined का मूल्य क्या है?

यह अपरिभाषित है : मानक इस मामले के बारे में कुछ नहीं कहता है।

foo::undefined लिए संभावित मूल्य foo::undefined :

  • उच्चतम संभव मान ( true ): undefined और oops का अंतर्निहित प्रकार अधिकतम मूल्य होना चाहिए।
  • न्यूनतम संभव मान ( false ): अंतर्निहित प्रकार का न्यूनतम मूल्य। नोट: हस्ताक्षरित पूर्णांकों में, यह पूर्णांक अतिप्रवाह (अपरिभाषित व्यवहार) के लिए वर्तमान व्यवहार से मेल नहीं खाएगा।
  • रैंडम वैल्यू (?): कंपाइलर मान का चयन करेगा।

इन सभी मूल्यों के साथ समस्या यह है कि यह एक ही मूल्य के साथ दो क्षेत्रों का परिणाम हो सकता है (उदाहरण के लिए foo::True == foo::undefined )।

इनिशियलाइज़र (जैसे undefined=2 ) और "निहित" इनिशियलाइज़र के बीच का अंतर (उदा। True=true, undefined )

मानक के अनुसार:

[ dcl.enum ] / 5 : यदि अंतर्निहित प्रकार तय हो गया है, तो समापन ब्रेस से पहले प्रत्येक प्रगणक का प्रकार अंतर्निहित प्रकार है और गणना-परिभाषा में निरंतर-अभिव्यक्ति अंतर्निहित प्रकार का एक परिवर्तित स्थिर अभिव्यक्ति होगी।

दूसरे शब्दों में:

 enum bar : bool { undefined=2 };

के बराबर है

 enum bar : bool { undefined=static_cast<bool>(2) };

और फिर bar::undefined true होगा। एक "निहित" इनिशियलाइज़र में, यह ऐसा नहीं होगा: यह मानक पैराग्राफ इसे केवल इनिशियलाइज़र के बारे में कहता है, न कि "इम्प्लांट" इनिशियलाइज़र के बारे में।

सारांश

  1. इस तरह, एक निश्चित-अंतर्निहित-प्रकार के साथ एक enum लिए संभव है कि अप्रमाणित मान हो।
  2. उनका मान मानक से अपरिभाषित है।

सवाल और टिप्पणियों के अनुसार, यह जीसीसी और क्लैंग में मान्य नहीं है लेकिन एमएसवीएस -2015 (चेतावनी के साथ) के लिए वैध है।





language-lawyer