क्लैंग / एलएलवीएम मुझे एक स्विच स्टेटमेंट में डिफ़ॉल्ट का उपयोग करने के बारे में चेतावनी क्यों देता है जहां सभी प्रगणित मामले कवर किए गए हैं?


34

निम्नलिखित एनम और स्विच स्टेटमेंट पर विचार करें:

typedef enum {
    MaskValueUno,
    MaskValueDos
} testingMask;

void myFunction(testingMask theMask) {
    switch (theMask) {
        case MaskValueUno: {}// deal with it
        case MaskValueDos: {}// deal with it
        default: {} //deal with an unexpected or uninitialized value
    }
};

मैं एक ऑब्जेक्टिव-सी प्रोग्रामर हूं, लेकिन मैंने इसे व्यापक दर्शकों के लिए शुद्ध सी में लिखा है।

क्लैंग / एलएलवीएम 4.1 के साथ-सब कुछ मुझे डिफ़ॉल्ट लाइन पर चेतावनी देता है:

स्विच में डिफ़ॉल्ट लेबल जो सभी गणन मूल्यों को कवर करता है

अब, मैं यह देख सकता हूं कि ऐसा क्यों है: एक आदर्श दुनिया में, तर्क में प्रवेश करने वाले एकमात्र मान एनम में theMaskहोंगे, इसलिए कोई डिफ़ॉल्ट आवश्यक नहीं है। लेकिन क्या होगा अगर कुछ हैक साथ आते हैं और मेरे सुंदर समारोह में एक अनैतिक रूप से अंतर डालते हैं? मेरे कार्य को पुस्तकालय में एक बूंद के रूप में प्रदान किया जाएगा, और वहां क्या हो सकता है, इस पर मेरा कोई नियंत्रण नहीं है। इसका उपयोग करना defaultबहुत ही आसान तरीका है।

एलएलवीएम देवता इस व्यवहार को अपने अयोग्य उपकरण के लिए अयोग्य क्यों मानते हैं? क्या मुझे तर्क की जांच करने के लिए एक बयान से पहले यह होना चाहिए?


1
मुझे कहना चाहिए, मेरा कारण-सब कुछ अपने आप को एक बेहतर प्रोग्रामर बनाना है। के रूप में NSHipster का कहना है : "Pro tip: Try setting the -Weverything flag and checking the “Treat Warnings as Errors” box your build settings. This turns on Hard Mode in Xcode."
स्विज़ल्र

2
-Weverythingउपयोगी हो सकता है, लेकिन इससे निपटने के लिए अपने कोड को बदलने के बारे में सावधान रहें। उन चेतावनियों में से कुछ न केवल बेकार हैं बल्कि प्रति-उत्पादक हैं, और सबसे अच्छी तरह से बंद हैं। (वास्तव में, इसके लिए उपयोग का मामला है -Weverything: इसके साथ शुरू करें, और बंद करें जो समझ में नहीं आता है।)
स्टीवन फिशर

क्या आप पोस्टिंग के लिए चेतावनी संदेश पर थोड़ा विस्तार कर सकते हैं? आमतौर पर उनसे ज्यादा है।
स्टीवन फिशर

उत्तर पढ़ने के बाद, मैं अभी भी आपके प्रारंभिक समाधान को प्राथमिकता देता हूं। डिफ़ॉल्ट स्टेटमेंट का उपयोग IMHO जवाबों में दिए गए विकल्पों से बेहतर है। बस एक छोटा नोट: जवाब वास्तव में अच्छे और जानकारीपूर्ण हैं, वे एक अच्छा तरीका दिखाते हैं कि समस्या को कैसे हल किया जाए।
बीबीजा ४२

@StevenFisher यह पूरी चेतावनी थी। और जैसा कि किलियन ने कहा है कि अगर मैं अपना एनम संशोधित करता हूं तो बाद में यह मान्य मानों के लिए डिफ़ॉल्ट कार्यान्वयन के लिए पारित होने की संभावना खोलेगा। यह एक अच्छा डिजाइन पैटर्न लगता है (यदि यह ऐसी बात है)।
स्विजलर

जवाबों:


31

यहां एक ऐसा संस्करण है जो न तो समस्या से जुड़ा है न ही क्लैंग की रिपोर्टिंग या आप के खिलाफ रख रहे हैं:

void myFunction(testingMask theMask) {
    assert(theMask == MaskValueUno || theMask == MaskValueDos);
    switch (theMask) {
        case MaskValueUno: {}// deal with it
        case MaskValueDos: {}// deal with it
    }
}

किलियन ने पहले ही समझाया है कि क्लैंग चेतावनी क्यों देता है: यदि आपने एनम बढ़ाया, तो आप डिफ़ॉल्ट मामले में गिर जाएंगे, जो शायद आप नहीं चाहते हैं। सही बात यह है कि डिफ़ॉल्ट मामले को हटा दें और अनचाही स्थितियों के लिए चेतावनी प्राप्त करें ।

अब आप चिंतित हैं कि कोई आपके फ़ंक्शन को मान के बाहर कह सकता है। ऐसा लगता है कि फ़ंक्शन की पूर्वापेक्षा को पूरा करने में विफल रहा है: यह प्रलेखित से एक मूल्य की उम्मीद करने के लिए प्रलेखित है, testingMaskलेकिन प्रोग्रामर ने कुछ और पारित कर दिया है। तो एक प्रोग्रामर त्रुटि का उपयोग करें assert()(या NSCAssert()जैसा कि आपने कहा था कि आप उद्देश्य-सी का उपयोग कर रहे हैं)। एक संदेश के साथ अपने प्रोग्राम को क्रैश करें यह समझाते हुए कि प्रोग्रामर गलत कर रहा है, अगर प्रोग्रामर यह गलत करता है।


6
+1। एक छोटे से संशोधन के रूप में, मैं प्रत्येक मामले को रखना पसंद करता हूं return;और assert(false);अंत में जोड़ता हूं (एक प्रारंभिक assert()और अंत में कानूनी दुश्मनी को सूचीबद्ध करके खुद को दोहराते हुए switch)।
जोश केली

1
क्या होगा अगर गलत गूंगा एक गूंगा प्रोग्रामर द्वारा पारित नहीं किया गया है, बल्कि एक स्मृति भ्रष्टाचार बग द्वारा? जब चालक अपने टोयोटा के ब्रेक को दबाता है और एक बग ने एनम को दूषित कर दिया है, तो ब्रेक-हैंडलिंग प्रोग्राम क्रैश और जलना चाहिए, और ड्राइवर को एक पाठ प्रदर्शित होना चाहिए: "प्रोग्रामर यह गलत कर रहा है, खराब प्रोग्रामर! "। इससे पहले कि वे एक चट्टान के किनारे पर ड्राइव करते हैं, मैं यह नहीं देख सकता कि यह कैसे उपयोगकर्ता की मदद करेगा।

2
@ लुंडिन यह है कि ओपी क्या कर रहा है, या यह कि आपके द्वारा अभी-अभी बनाए गए एक निरर्थक सैद्धांतिक किनारे का मामला है? भले ही, एक "मेमोरी भ्रष्टाचार बग" [i] प्रोग्रामर त्रुटि है, [ii] कुछ ऐसा नहीं है जिसे आप सार्थक तरीके से जारी रख सकते हैं (कम से कम प्रश्न में बताई गई आवश्यकताओं के साथ नहीं)।

1
@GrahamLee मैं सिर्फ इतना कह रहा हूं कि जब आप एक अप्रत्याशित त्रुटि करते हैं तो "लेट एंड डाई" जरूरी नहीं कि सबसे अच्छा विकल्प हो।

1
इसमें नई समस्या यह है कि आप दावा कर सकते हैं और मामले दुर्घटनावश सिंक से बाहर हो सकते हैं।
user253751

9

defaultयहां एक लेबल होना एक संकेतक है जिसे आप इस बारे में भ्रमित कर रहे हैं कि आप क्या अपेक्षा कर रहे हैं। चूंकि आपने सभी संभावित enumमूल्यों को स्पष्ट रूप से समाप्त defaultकर दिया है, इसलिए संभवतः निष्पादित नहीं किया जा सकता है, और आपको भविष्य में होने वाले परिवर्तनों से बचने के लिए इसकी आवश्यकता नहीं है, क्योंकि यदि आपने इसे बढ़ाया है enum, तो निर्माण पहले से ही एक चेतावनी उत्पन्न करेगा ।

तो, संकलक नोटिस कि आप सभी ठिकानों को कवर किया, लेकिन दिखाई है किया जाना है सोच है कि आप नहीं है, और है कि हमेशा एक बुरा संकेत है। switchअपेक्षित रूप को बदलने के लिए न्यूनतम प्रयास करके , आप संकलक को प्रदर्शित करते हैं कि आप जो करते दिख रहे हैं वह वही है जो आप वास्तव में कर रहे हैं, और आप इसे जानते हैं।


1
लेकिन मेरी चिंता एक गंदा चर है, और उस के खिलाफ रखवाली करना (जैसे कि, मैंने कहा, एक अनैतिक रूप से int)। मुझे ऐसा लगता है कि ऐसी स्थिति में डिफ़ॉल्ट रूप से स्विच स्टेटमेंट तक पहुंचना संभव होगा।
स्विजलर

मुझे दिल से ऑब्जेक्टिव-सी की परिभाषा नहीं पता है, लेकिन मैंने यह मान लिया था कि कंपाइलर द्वारा एक टाइपडेफैम एनम लागू किया जाएगा। दूसरे शब्दों में, "अनइंस्टॉलिज्ड" वैल्यू केवल विधि में प्रवेश कर सकती है यदि आपका प्रोग्राम पहले से ही अपरिभाषित व्यवहार प्रदर्शित करता है, और मुझे यह पूरी तरह से उचित लगता है कि एक कंपाइलर इसे ध्यान में नहीं रखता है।
किलन फ़ॉथ

3
@KilianFoth नहीं, वे नहीं हैं। ऑब्जेक्टिव-सी एनम सी एनम हैं, जावा एनम नहीं। अंतर्निहित अभिन्न प्रकार से कोई भी मान फ़ंक्शन तर्क में मौजूद हो सकता है।

2
इसके अलावा, एनमर्स को रनटाइम में पूर्णांक से सेट किया जा सकता है। तो वे किसी भी मूल्य की कल्पना कर सकते हैं।

ओपी सही है। परीक्षणमस्क m; myfunction (एम); सबसे अधिक संभावना डिफ़ॉल्ट मामले को मारा जाएगा।
मैथ्यू जेम्स ब्रिग्स 5

4

क्लैंग उलझन में है, एक डिफ़ॉल्ट बयान होने पर पूरी तरह से ठीक अभ्यास है, इसे रक्षात्मक प्रोग्रामिंग के रूप में जाना जाता है और इसे अच्छा प्रोग्रामिंग अभ्यास (1) माना जाता है। यह मिशन-क्रिटिकल सिस्टम में बहुत उपयोग किया जाता है, हालांकि शायद डेस्कटॉप प्रोग्रामिंग में नहीं।

रक्षात्मक प्रोग्रामिंग का उद्देश्य अप्रत्याशित त्रुटियों को पकड़ना है जो सिद्धांत रूप में कभी नहीं होगा। इस तरह की अप्रत्याशित त्रुटि जरूरी नहीं है कि प्रोग्रामर फ़ंक्शन को गलत इनपुट दे, या यहां तक ​​कि "बुराई हैक" भी कर सकता है। अधिक संभावना है, यह एक भ्रष्ट चर के कारण हो सकता है: बफर ओवरफ्लो, स्टैक ओवरफ़्लो, रनवे कोड और आपके फ़ंक्शन से संबंधित समान बग इसके कारण नहीं हो सकते हैं। और एम्बेडेड सिस्टम के मामले में, संभवतः EMI के कारण चर बदल सकते हैं, खासकर यदि आप बाहरी रैम सर्किट का उपयोग कर रहे हैं।

डिफॉल्ट स्टेटमेंट के अंदर क्या लिखते हैं ... यदि आपको संदेह है कि आपके समाप्त होने के बाद प्रोग्राम हाइरवायर हो गया है, तो आपको किसी प्रकार की त्रुटि से निपटने की आवश्यकता है। कई मामलों में आप शायद केवल एक टिप्पणी के साथ एक खाली बयान जोड़ सकते हैं: "अप्रत्याशित लेकिन कोई फर्क नहीं पड़ता" आदि, यह दिखाने के लिए कि आपने अप्रत्याशित स्थिति के बारे में सोचा है।


(१) मीसा-सी: २००४ १५.३


1
ऐसा नहीं है कि औसत पीसी प्रोग्रामर आमतौर पर रक्षात्मक प्रोग्रामिंग की अवधारणा को पूरी तरह से अलग-थलग पाता है, क्योंकि एक कार्यक्रम के बारे में उनका दृष्टिकोण एक अमूर्त यूटोपिया है जहां कुछ भी गलत नहीं है जो सिद्धांत में गलत हो सकता है। इसलिए आपको अपने प्रश्न के आधार पर काफी विविधतापूर्ण उत्तर मिलेंगे जो आप पूछते हैं।

3
क्लैंग भ्रमित नहीं है; यह स्पष्ट रूप से सभी चेतावनी प्रदान करने के लिए कहा गया है , जिसमें वे शामिल हैं जो हमेशा उपयोगी नहीं होते हैं, जैसे कि शैलीगत चेतावनी। (मैं व्यक्तिगत रूप से इस चेतावनी का विकल्प चुनता हूं क्योंकि मैं अपने एनम स्विच में चूक नहीं करना चाहता हूं, उनका मतलब है कि मुझे एक चेतावनी नहीं मिलती है यदि मैं एक एनम मूल्य जोड़ता हूं और इसे संभाल नहीं करता हूं। इस कारण से, मैं हमेशा संभालता हूं। एनम के बाहर खराब मूल्य का मामला।)
जेन्स एटन

2
@ जेंसएटन यह भ्रमित है। सभी पेशेवर स्थिर विश्लेषक उपकरण और साथ ही सभी MISRA- संगत संकलक एक चेतावनी देंगे यदि स्विच स्टेटमेंट में डिफ़ॉल्ट स्टेटमेंट का अभाव है। खुद एक कोशिश करो।

4
MISRA-C के लिए कोडिंग C कंपाइलर के लिए एकमात्र वैध उपयोग नहीं है, और, फिर से, प्रत्येक चेतावनी को -Weverythingचालू करता है , न कि किसी विशेष उपयोग के मामले के लिए उपयुक्त चयन। अपने स्वाद फिटिंग नहीं भ्रम के रूप में एक ही बात नहीं है।
जेन्स एटन

2
@ लुंडिन: मुझे पूरा यकीन है कि MISRA-C से चिपके रहने से जादुई रूप से कार्यक्रम सुरक्षित और बग-मुक्त नहीं हो जाते ... और मुझे भी उतना ही यकीन है कि ऐसे लोगों से बहुत सुरक्षित, बग-मुक्त सी कोड है जो कभी भी नहीं थे MISRA के बारे में सुना । वास्तव में, यह किसी के (लोकप्रिय, लेकिन निर्विवाद नहीं) राय से थोड़ा अधिक है, और ऐसे लोग हैं जो इसके कुछ नियमों को मनमाना पाते हैं और कभी-कभी संदर्भ के बाहर भी हानिकारक होते हैं जिसके लिए उन्हें डिज़ाइन किया गया था।
cHao

4

फिर भी बेहतर:

typedef enum {
    MaskValueUno,
    MaskValueDos,

    MaskValue_count
} testingMask;

void myFunction(testingMask theMask) {
    assert(theMask >= 0 && theMask<MaskValue_count);
    switch theMask {
        case MaskValueUno: {}// deal with it
        case MaskValueDos: {}// deal with it
    }
};

एनम में आइटम जोड़ते समय यह कम त्रुटि वाला है। यदि आप अपने enum मानों को अहस्ताक्षरित करते हैं, तो आप> = 0 के लिए परीक्षण को छोड़ सकते हैं। यह विधि केवल तभी काम करती है जब आपको अपने एनम मूल्यों में कोई अंतराल न हो, लेकिन अक्सर ऐसा होता है।


2
यह प्रकार को उन मानों के साथ प्रदूषित कर रहा है जो आप नहीं चाहते हैं कि प्रकार शामिल है। यहाँ अच्छे पुराने WTF के साथ समानताएँ हैं: thedailywtf.com/articles/What_Is_Truth_0x3f_
मार्टिन सुगियोआर्टो

4

लेकिन क्या होगा अगर कुछ हैक साथ आते हैं और मेरे सुंदर समारोह में एक अनैतिक रूप से अंतर डालते हैं?

तब आप अनिर्धारित व्यवहार प्राप्त करते हैं, और आपका defaultअर्थहीन हो जाएगा। ऐसा कुछ नहीं है जो आप संभवतः इसे किसी भी बेहतर बनाने के लिए कर सकते हैं।

मुझे और स्पष्ट होने दो। तत्काल कोई व्यक्ति intआपके फ़ंक्शन में एक असंवैधानिक रूप से गुजरता है , यह अपरिभाषित व्यवहार है। आपका कार्य हल करने की समस्या को हल कर सकता है और इससे कोई फर्क नहीं पड़ेगा। यह यूबी है। एक बार यूबी लागू होने के बाद आप कुछ भी नहीं कर सकते हैं।


3
कैसे इसके बारे में लॉग इन करें या इसके बजाय एक अपवाद फेंक दें अगर चुपचाप इसे अनदेखा करें?
jgauffin

3
वास्तव में, बहुत कुछ है जो किया जा सकता है, जैसे ... स्विच में डिफ़ॉल्ट स्टेटमेंट जोड़ना और इनायत त्रुटि को संभालना। इसे रक्षात्मक प्रोग्रामिंग के रूप में जाना जाता है । यह न केवल गूंगा प्रोग्रामर को फ़ंक्शन को गलत इनपुट सौंपने से बचाएगा, बल्कि बफर ओवरफ़्लो, स्टैक ओवरफ़्लो, रनवे कोड आदि के कारण होने वाले विभिन्न बगों के खिलाफ भी होगा

1
नहीं, यह कुछ भी नहीं संभालेंगे। यह यूबी है। कार्यक्रम में यूबी है जिस क्षण फ़ंक्शन दर्ज किया गया है, और फ़ंक्शन बॉडी इसके बारे में कुछ भी नहीं कर सकता है।
डेडएमजी डेसी

2
@DeadMG एक एनम का कोई भी मूल्य हो सकता है जो कार्यान्वयन में उसके संबंधित पूर्णांक प्रकार के हो सकते हैं। इसके बारे में कुछ भी अपरिभाषित नहीं है। एक गैर-विनिर्मित ऑटो चर की सामग्री तक पहुंचना वास्तव में यूबी है, लेकिन "बुराई हैक" (जो कि किसी प्रकार की बग की संभावना है) समारोह में अच्छी तरह से परिभाषित मूल्य को टॉस कर सकता है, भले ही यह मूल्यों में से एक न हो। एनम घोषणा में सूचीबद्ध है।

2

डिफ़ॉल्ट बयान जरूरी मदद नहीं करेगा। यदि स्विच एक एनम के ऊपर है, तो एनम में परिभाषित कोई भी मान अपरिभाषित व्यवहार को समाप्त नहीं करेगा।

आप सभी जानते हैं, संकलक उस स्विच को (डिफ़ॉल्ट के साथ) संकलित कर सकता है:

if (theMask == MaskValueUno)
  // Execute something MaskValueUno code
else // theMask == MaskValueDos
  // Execute MaskValueDos code

एक बार जब आप अपरिभाषित व्यवहार को ट्रिगर करते हैं, तो कोई पीछे नहीं जाता है।


2
सबसे पहले, यह अनिर्दिष्ट मूल्य है , अपरिभाषित व्यवहार नहीं। इसका मतलब यह है कि संकलक कुछ अन्य मूल्य मान सकता है जो अधिक सुविधाजनक है, लेकिन यह चंद्रमा को हरी चीज में नहीं बदल सकता है, आदि दूसरी बात, जहां तक ​​मैं बता सकता हूं, यह केवल C ++ पर लागू होता है। C में, किसी enumप्रकार के मानों की श्रेणी उसके अंतर्निहित पूर्णांक प्रकार के मूल्यों की श्रेणी के समान होती है (जो कि कार्यान्वयन-परिभाषित है, इसलिए आत्म-सुसंगत होना चाहिए)।
जेन्स एटन

1
हालांकि, एक एनम चर और एक गणना निरंतर की एक उदाहरण के लिए जरूरी नहीं कि एक ही चौड़ाई और हस्ताक्षर की आवश्यकता है, वे दोनों निहित हैं। लेकिन मुझे पूरा यकीन है कि सी में सभी एनमों का मूल्यांकन उनके संबंधित पूर्णांक प्रकार की तरह किया जाता है, इसलिए वहां कोई अनिर्धारित या अनिर्दिष्ट व्यवहार नहीं है।

2

मैं भी default:सभी मामलों में एक है पसंद करते हैं । मुझे पार्टी में हमेशा की तरह देर हो रही है, लेकिन ... कुछ अन्य विचार जो मैंने ऊपर नहीं देखे:

  • विशेष चेतावनी (या अगर फेंक भी त्रुटि -Werror) से आ रही है -Wcovered-switch-default( -Weverythingलेकिन नहीं -Wall)। अपने नैतिक लचीलापन आप चालू करने के लिए अनुमति देता है बंद कुछ चेतावनी (यानी, से कुछ चीजों की आबकारी -Wallया -Weverything), फेंकने पर विचार -Wno-covered-switch-default(या -Wno-error=covered-switch-defaultका उपयोग करते समय -Werror), और सामान्य रूप में -Wno-...अन्य चेतावनियों के लिए आप अप्रिय पाते हैं।
  • के लिए gcc(और में अधिक सामान्य व्यवहार clang), परामर्श gccके लिए मैनपेज -Wswitch, -Wswitch-enum, -Wswitch-defaultके लिए (अलग) स्विच बयान में प्रगणित प्रकार के इसी तरह की परिस्थितियों में व्यवहार।
  • मुझे अवधारणा में यह चेतावनी पसंद नहीं है, और मुझे इसका शब्दांकन पसंद नहीं है; मेरे लिए, चेतावनी से शब्द ("डिफ़ॉल्ट लेबल ... सभी को कवर करता है ... मान") सुझाव देते हैं कि default:मामले को हमेशा निष्पादित किया जाएगा, जैसे कि

    switch (foo) {
      case 1:
        do_something(); 
        //note the lack of break (etc.) here!
      default:
        do_default();
    }

    पहली बार पढ़ने पर, यह मैं क्या सोचा कि आप में चल रहे थे है - कि आपके default:मामले हमेशा है, क्योंकि वहाँ कोई निष्पादित किया जाएगा break;या return;या इसी तरह की। यह अवधारणा अन्य नानी-शैली के समान (मेरे कान के लिए) (यद्यपि कभी-कभी सहायक होती है) कमेंट्री से सामने आती है clang। यदि foo == 1, दोनों कार्यों को निष्पादित किया जाएगा; आपके कोड के ऊपर यह व्यवहार है। यानी, यदि आप संभवतः बाद के मामलों से कोड निष्पादित करना चाहते हैं तो केवल ब्रेक-आउट करने में विफल रहें! हालांकि, यह आपकी समस्या नहीं है।

पांडित्य होने के जोखिम पर, पूर्णता के लिए कुछ अन्य विचार:

  • हालाँकि मुझे लगता है कि यह व्यवहार अन्य भाषाओं या संकलक में आक्रामक प्रकार की जाँच के अनुरूप (अधिक) है। , तो के रूप में आप परिकल्पना, कुछ बदमाश है एक पारित करने के लिए प्रयास करने के intलिए इस समारोह है, जो स्पष्ट रूप से अपने स्वयं के विशिष्ट प्रकार का उपभोग करने के लिए इच्छुक है करने के लिए या कुछ और, अपने संकलक एक आक्रामक चेतावनी या त्रुटि के साथ उस स्थिति में समान रूप से अच्छी तरह से आप की रक्षा करना चाहिए। लेकिन यह नहीं है! (यही है, ऐसा लगता है कि कम से कम gccऔर टाइप-चेकिंग clangन करें enum, लेकिन मुझे लगता है कि iccऐसा करता है )। चूँकि आप टाइप -सैफ़टी नहीं कर रहे हैं , आप ऊपर चर्चा के अनुसार मूल्य- सफ़लिटी प्राप्त कर सकते हैं । अन्यथा, जैसा कि टीएफए में सुझाव दिया गया है, एक structया ऐसी चीज पर विचार करें जो टाइप-सेफ्टी प्रदान कर सके।
  • एक और वर्कअराउंड आपके enumजैसे एक नया "मूल्य" बना सकता है MaskValueIllegal, और caseआपके समर्थन में नहीं switch। वह default:(किसी भी निराला मूल्य के अलावा) द्वारा खाया जाएगा

लंबे समय तक रक्षात्मक कोडिंग!


1

यहां एक वैकल्पिक सुझाव दिया गया है:
ओपी उस मामले से बचाव करने की कोशिश कर रहा है, जहां कोई व्यक्ति ऐसी जगह से गुजरता है intजहां एक एनम की उम्मीद की जाती है। या, अधिक संभावना है, जहां किसी ने एक पुराने पुस्तकालय को नए हेडर के साथ नए मामलों में अधिक मामलों के साथ जोड़ा है।

intकेस को संभालने के लिए स्विच क्यों नहीं बदला ? स्विच में मूल्य के सामने एक डाली जोड़ने से चेतावनी समाप्त हो जाती है और यहां तक ​​कि डिफ़ॉल्ट मौजूद क्यों है के बारे में संकेत की एक डिग्री प्रदान करता है।

void myFunction(testingMask theMask) {
    int maskValue = int(theMask);
    switch(maskValue) {
        case MaskValueUno: {} // deal with it
        case MaskValueDos: {}// deal with it
        default: {} //deal with an unexpected or uninitialized value
    }
}

मुझे प्रत्येक संभावित मानों के परीक्षण की तुलना में यह बहुत कम आपत्तिजनक लगता है assert()या यहां तक ​​कि यह धारणा बनाते हुए कि Enum मानों की सीमा अच्छी तरह से क्रमबद्ध है ताकि एक सरल परीक्षण काम करे। यह डिफ़ॉल्ट रूप से ठीक और सुंदर तरीके से करने का एक बदसूरत तरीका है।


1
यह पोस्ट पढ़ना मुश्किल है (पाठ की दीवार)। आप आपत्ति तो नहीं है संपादित एक बेहतर आकार में यह ing?
gnat
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.