मानक के अनुसार रंग सेट क्या है?
C ++ 11 और C ++ 14 मानकों के एक उद्धरण के साथ उत्तर देना:
[Expr.static.cast] / 10
अभिन्न या गणना प्रकार का मान स्पष्ट रूप से एक गणना प्रकार में परिवर्तित किया जा सकता है। मान अपरिवर्तित है यदि मूल मान गणना मूल्यों (7.2) की सीमा के भीतर है। अन्यथा, परिणामी मान अनिर्दिष्ट है (और उस सीमा में नहीं हो सकता है)।
आइए गणना के मानों की सीमा देखें : [dcl.enum] / 7
एक गणना के लिए जिसका अंतर्निहित प्रकार तय हो गया है, गणना के मान अंतर्निहित प्रकार के मूल्य हैं।
CWG 1766 (C ++ 11, C ++ 14) से पहले
, इसलिए, data[0] == 100जिसके परिणामस्वरूप परिणाम निर्दिष्ट है (*), और कोई अपरिभाषित व्यवहार (UB) शामिल नहीं है। आम तौर पर, जैसा कि आप अंतर्निहित प्रकार से एन्यूमरेशन प्रकार data[0]तक डालते हैं, यूबी के लिए कोई मूल्य नहीं हो सकता है static_cast।
CWG 1766 (C ++ 17)
के बाद CWG दोष 1766 देखें । [Expr.static.cast] p10 पैराग्राफ को मजबूत किया गया है, इसलिए अब आप यूबी को लागू कर सकते हैं यदि आप एक मान को एनम के प्रकार के प्रतिनिधित्व योग्य सीमा के बाहर रखते हैं। यह अभी भी प्रश्न में परिदृश्य पर लागू नहीं होता है, क्योंकि data[0]अंतर्निहित प्रकार की गणना है (ऊपर देखें)।
कृपया ध्यान दें कि CWG 1766 को मानक में एक दोष माना जाता है, इसलिए यह कंपाइलर कार्यान्वयनकर्ताओं के लिए उनके C ++ 11 और C ++ 14 संकलन मोड पर लागू करने के लिए स्वीकार किया जाता है।
(*) charकम से कम 8 बिट चौड़ा होना आवश्यक है, लेकिन होना आवश्यक नहीं है unsigned। अधिकतम मूल्य कम से कम 127C99 मानक के अनुलग्नक ई प्रति कम से कम होना आवश्यक है ।
[Expr] / 4 से तुलना करें
यदि किसी अभिव्यक्ति के मूल्यांकन के दौरान, परिणाम गणितीय रूप से परिभाषित नहीं है या अपने प्रकार के लिए प्रतिनिधित्व योग्य मूल्यों की सीमा में नहीं है, तो व्यवहार अपरिभाषित है।
सीडब्ल्यूजी 1766 से पहले, रूपांतरण अभिन्न प्रकार -> गणना प्रकार एक अनिर्दिष्ट मूल्य का उत्पादन कर सकता है । सवाल यह है कि क्या एक अनिर्दिष्ट मूल्य अपने प्रकार के लिए प्रतिनिधित्व योग्य मूल्यों से बाहर हो सकता है? मेरा मानना है कि उत्तर नहीं है - यदि उत्तर हाँ था , तो "इस ऑपरेशन से एक अनिर्दिष्ट मूल्य पैदा होता है" और "इस ऑपरेशन का अपरिभाषित व्यवहार होता है" के बीच गारंटीकृत प्रकारों के लिए आपको मिलने वाली गारंटी में कोई अंतर नहीं होगा।
इसलिए, CWG 1766 से पहले, यहां तक static_cast<Color>(10000)कि UB को भी आमंत्रित नहीं किया जाएगा ; लेकिन CWG 1766 के बाद, यह UB को लागू करता है ।
अब, switchबयान:
[Stmt.switch] / 2
स्थिति अभिन्न प्रकार, गणना प्रकार या वर्ग प्रकार की होगी। [...] अभिन्न प्रचार किया जाता है।
[Conv.prom] / 4
एक का एक prvalue unscoped गणना प्रकार जिसका अंतर्निहित प्रकार तय हो गई है (7.2) उसके अंतर्निहित प्रकार का एक prvalue में बदला जा सकता। इसके अलावा, अगर इंटीग्रल प्रमोशन को इसके अंतर्निहित प्रकार पर लागू किया जा सकता है, तो एक अनकैप्ड एन्यूमरेशन प्रकार का एक प्रचलन, जिसका अंतर्निहित प्रकार तय हो गया है, को भी प्रमोट किए गए अंतर्निहित प्रकार के एक प्रिव्यू में बदला जा सकता है।
नोट: स्कूप्ड एनम डब्ल्यू / ओ एनम-बेस का अंतर्निहित प्रकार है int। Unscoped enums के लिए अंतर्निहित प्रकार कार्यान्वयन से परिभाषित है, लेकिन से बड़ा नहीं होगा intअगर intसभी प्रगणक के मान हो सकते हैं।
एक असंगत गणना के लिए , यह हमें / 1 तक ले जाता है
एक पूर्णांक के अलावा अन्य प्रकार का एक prvalue bool, char16_t, char32_t, या wchar_tजिसका पूर्णांक रूपांतरण रैंक (4.13) के पद से भी कम है intप्रकार का एक prvalue में बदला जा सकता intहै, तो intस्रोत प्रकार के सभी मूल्यों का प्रतिनिधित्व कर सकते हैं; अन्यथा, स्रोत प्रचलन को प्रकार के एक प्रचलन में परिवर्तित किया जा सकता है unsigned int।
एक अप्रकाशित गणना के मामले में , हम intयहां एस के साथ काम करेंगे । के लिए दायरे वाला enumerations ( enum classऔर enum struct), कोई अभिन्न पदोन्नति लागू होता है। किसी भी तरह से, अभिन्न पदोन्नति यूबी के लिए नेतृत्व नहीं करता है, क्योंकि संग्रहीत मूल्य अंतर्निहित प्रकार की सीमा में और सीमा की सीमा में है int।
[Stmt.switch] / 5
जब switchकथन निष्पादित किया जाता है, तो इसकी स्थिति का मूल्यांकन किया जाता है और प्रत्येक मामले के साथ तुलना की जाती है। यदि मामले में से एक स्थिरांक स्थिति के मूल्य के बराबर है, तो नियंत्रण को मिलान caseलेबल के बाद बयान में पारित किया जाता है । यदि कोई caseस्थिरांक स्थिति से मेल नहीं खाता है, और यदि कोई defaultलेबल है, तो लेबल द्वारा लेबल किए गए स्टेटमेंट पर नियंत्रण पास हो जाता है default।
defaultलेबल मारा जाना चाहिए।
नोट: एक तुलना ऑपरेटर पर एक और नज़र डाल सकता है, लेकिन यह स्पष्ट रूप से संदर्भित "तुलना" में उपयोग नहीं किया जाता है। वास्तव में, यह कोई संकेत नहीं है कि यह हमारे मामले में स्कोप या अनकैप्ड एनम के लिए यूबी को पेश करेगा।
एक बोनस के रूप में, मानक इस बारे में कोई गारंटी देता है लेकिन सादे एनम के साथ?
enumस्कोप किया गया है या नहीं, इससे कोई फर्क नहीं पड़ता। हालाँकि, इससे कोई फ़र्क पड़ता है कि अंतर्निहित प्रकार निश्चित है या नहीं। पूरा [घोषणा.नाम] / 7 है:
एक गणना के लिए जिसका अंतर्निहित प्रकार तय हो गया है, गणना के मान अंतर्निहित प्रकार के मूल्य हैं। अन्यथा, एक गणन जहां के लिए ई मिनट छोटी से छोटी प्रगणक और है ई अधिकतम सबसे बड़ा है, गणन के मूल्यों मूल्यों श्रेणी में हैं ख मिनट के लिए ख अधिकतम , परिभाषित इस प्रकार है: Let Kहोना 1एक दो के पूरक प्रतिनिधित्व के लिए और 0एक के लिए किसी का पूरक या संकेत-परिमाण प्रतिनिधित्व। b मैक्स अधिकतम से बड़ा या बराबर का सबसे छोटा मान है (| e min | - K; | e max |) और 2 के बराबरएम - 1 , जहांMएक गैर-नकारात्मक पूर्णांक है। ख मिनट शून्य है अगर ई मिनट गैर नकारात्मक है और - (ख अधिकतम + K) अन्यथा।
आइए निम्नलिखित गणना पर एक नज़र डालें:
enum ColorUnfixed /* no fixed underlying type */
{
red = 0x1,
yellow = 0x2
}
ध्यान दें कि हम इसे स्कूप्ड एनम के रूप में परिभाषित नहीं कर सकते हैं, क्योंकि सभी स्कॉप्ड एनम में अंतर्निहित प्रकार तय किए गए हैं।
सौभाग्य से, ColorUnfixedसबसे छोटा प्रगणक है red = 0x1, इसलिए अधिकतम (| ई मिनट | - K; | ई अधिकतम |) बराबर है । ई अधिकतम | किसी भी मामले में, जो है yellow = 0x2। सबसे छोटा मान या उससे अधिक 2, जो एक सकारात्मक पूर्णांक के लिए 2 M - 1 के बराबर Mहै 3( 2 2 - 1 ) है। (मुझे लगता है कि इरादा सीमा को 1-बिट-चरणों में सीमित करने की अनुमति है।) यह निम्न प्रकार है कि b अधिकतम है 3और bmin है 0।
इसलिए, 100की सीमा के बाहर होगा ColorUnfixed, और static_castCWG 1766 से पहले एक अनिर्दिष्ट मूल्य का उत्पादन करेगा और CWG 1766 के बाद अपरिभाषित व्यवहार करेगा।
char, इसलिए "मूल मान अपरिवर्तित (7.2 मान) की सीमा के भीतर है, तो अपरिवर्तित है।" लागू होता है।