2011-05-23 11 views
16

में स्विच स्टेटमेंट में संभाला नहीं जाता है, तो मैं एक कम्पाइलर चेतावनी या त्रुटि प्राप्त करना चाहता हूं, जब स्विच कथन में सभी संभावित एनम मानों को संभाला नहीं जाता है। बेशक मैं एक आवेदक के साथ एक डिफ़ॉल्ट मामला जोड़ सकता हूं और (अंत में) रनटाइम पर एक त्रुटि प्राप्त कर सकता है। लेकिन मैं संकलन समय पर एक त्रुटि प्राप्त करना चाहता हूं।संकलन-समय पर जोर दें जब सभी enum मानों को C++

मुझे यकीन है कि नहीं कर रहा हूँ अगर यह सब पर सी ++ के साथ संभव है, लेकिन शायद किसी को एक चाल जानता है ...

संपादित करें: का उपयोग -Wswitch जीसीसी के लिए समाधान हो रहा है। क्या वीएस -2010 के लिए कुछ समान है? (मैं जीसीसी का उपयोग नहीं कर रहा हूं)।

EDIT2: जब एक मूल्य und कोई डिफ़ॉल्ट मामले प्रदान की जाती है याद आ रही है

सक्षम करने की चेतावनी C4062 एक चेतावनी का उत्पादन: ठीक है, मैं कुलपति ++ (VS2010) के लिए समाधान मिल गया।

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

+1

कौन सा संकलक? –

उत्तर

6

आपने उल्लेख नहीं किया है कि आप किस कंपाइलर का उपयोग कर रहे हैं। यदि आप जीसीसी का उपयोग कर रहे हैं, तो आप इसे आसानी से -Wswitch सक्षम करके प्राप्त कर सकते हैं (जो -Wall द्वारा स्वचालित रूप से सक्षम है)।

1

g ++ स्वचालित रूप से ऐसा करता है यदि आप -Wall के साथ सभी चेतावनियां सक्षम करते हैं।

4

यदि आप -Wall के साथ g ++ का उपयोग कर रहे हैं, तो आप इसे प्राप्त करेंगे।

उदाहरण के लिए, इस:

enum Abc 
{ 
    A =1, 
    B, 
    C 
}; 

Abc a = A; 
switch(a) 
{ 
case A: 
    break; 
case B: 
    break; 
} 

एक चेतावनी पैदा करने के लिए जा रहा है।

लेकिन असफल दावा के साथ default केस का उपयोग करना बेहतर है, क्योंकि जब आप एक नया एनम मान जोड़ते हैं, तो आपको उन सभी फ़ाइलों को बदलना होगा जहां आप इस enum पर स्विच का उपयोग कर रहे हैं।

+3

यह एक कारण की तरह लगता है * नहीं * 'डिफ़ॉल्ट' का उपयोग करने के लिए! निश्चित रूप से आप संकलक चाहते हैं कि समस्या को मुखौटा करने के बजाय, 'enum' स्थानों का पता लगाने में आपकी सहायता करें? –

+0

@ ओली यह आपकी प्राथमिकताओं पर निर्भर करता है। यदि आपको कंपाइलर चेतावनियां पसंद हैं, तो एक एनम जोड़कर आप सभी स्विच बदल सकते हैं। यदि आप रन-टाइम चेतावनी को प्राथमिकता देते हैं, तो आप कोड के छोटे टुकड़ों (विभाजन और जीत) पर ध्यान केंद्रित कर सकते हैं। –

+3

@VJo: आपको ** हमेशा ** कंपाइलर चेतावनियों (त्रुटियों, आदर्श रूप में) पसंद करते हैं जहां वे उपलब्ध हैं।रन-टाइम चेतावनियों पर निर्भर होने का अर्थ है कि आप यह सुनिश्चित नहीं कर सकते कि सबकुछ ठीक हो गया है जब तक कि आप हर संभव इनपुट संयोजन के साथ हर संभव कोड पथ नहीं चलाते; यह कट्टरपंथी है अगर संकलक आपके लिए यह स्पष्ट रूप से स्पॉट करेगा! –

2

AFAIK एमएसवीसी के साथ आप जो चाहते हैं उसे प्राप्त करने के लिए कोई पारंपरिक तरीका नहीं है। समान चीजें करने के लिए चाल हैं, लेकिन उनमें या तो एक परिष्कृत टेम्पलेट वूडू, या वास्तव में भयंकर मैक्रोज़ पहेलियों शामिल हैं।

उदाहरण के लिए, बजाय एक पारंपरिक तरीके से अपने enum को परिभाषित करने के निम्न करें:

#define MyEnumEntries(m) \ 
    m(A, 1) \ 
    m(B, 2) \ 
    m(C, 3) \ 

enum Abc { 

    // the following will expand into your enum values definitions 
# define M_Decl(name, value) name = value, 
    MyEnumEntries(M_Decl) 
}; 

अब, अपने स्विच इस में फिर से लिखा जा सकता है:

Abc a = A; 

switch(a) 
{ 
#define M_Goto(name, value) \ 
case value: 
    goto label_##name; 

MyEnumEntries(M_Goto) 


case label_A: 
    // TODO 
    break; 
case label_B: 
    // TODO 
    break; 
} 

ऊपर यदि संकलन नहीं होगा आप सभी enum मानों के लिए स्विच प्रविष्टि label_... नहीं जोड़ेंगे।

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