2016-08-26 8 views
8
बचें

के एक (foo.lst) मानों की सूची करते हैं :गलत सकारात्मक -Wswitch चेतावनी

int main(void) { 
    enum foo[_foo_length]; 

    switch(f[0]) { 
    case foo: return 0; 
    case bar: return 0; 
    case baz: return 0; 
    } 

    __builtin_unreachable(); 
} 

(इस कोड को गूंगा है, लेकिन सिर्फ उपेक्षा कि)

,210

समस्या: -Wswitch (-Wall में शामिल है) के साथ
, जीसीसी और बजना (और शायद अन्य) चेतावनी देगा:

चेतावनी: गणन मान '_foo_length' स्विच में नहीं संभाला [-Wswitch]

समाधान:

  • अक्षम करना -Wno-switch कि चेतावनी छुपाता है।
    डाउनसाइड: हम स्विच से गायब किसी अन्य case के बारे में चेतावनियां खो देते हैं।
  • default: unreachable(); मामले जोड़ना।
    डाउनसाइड: यदि हम डीबगिंग करते समय किसी भी लापता मामलों में से किसी एक को हिट करते हैं तो हम रनटाइम दुर्घटना के पक्ष में लापता मामलों की संकलन-समय चेतावनियां खो देते हैं।
  • #define _foo_length (baz + 1) के साथ enum के अंतिम मान को प्रतिस्थापित करना, इसे अब enum का हिस्सा नहीं बना रहा है।
    डाउनसाइड: यह आवश्यक है कि जब भी सूची में कोई मूल्य जोड़ा जाता है तो उसे मैन्युअल रूप से अपडेट किया जाना चाहिए। कोई भी हमेशा भूल जाएगा, सबकुछ तोड़ देगा।

आदर्श रूप में, वहाँ एक रास्ता नहीं किया जा रहा है आबंटित के रूप में एक enum के मूल्य को चिह्नित है, जिससे जब संभव मूल्यों को पढ़ने यह संकलक में एक चेतावनी का उत्पादन नहीं कर रही है और यह एक वहाँ नहीं है, आवश्यकता के बिना किया जाना चाहिए प्रीप्रोसेसर मैक्रो को डुप्लिकेट संशोधनों की आवश्यकता होती है।

क्या ऐसा कुछ भी है? कोई अन्य विकल्प मैंने नहीं सोचा था?

+0

चूंकि आप गतिशील रूप से enum बना रहे हैं, तो आप कैसे सुनिश्चित कर सकते हैं कि 'स्विच' वास्तव में सभी मामलों को शामिल करता है? – Barmar

+0

और क्या होता है यदि फ़ाइल में से कोई एक मामला नहीं है? यह पूरी बात मेरे लिए गलत गंध करता है। – Barmar

+2

आप एक मामला _foo_length जोड़ सकते हैं: ' – Barmar

उत्तर

2

उपयोग

case _foo_length: 
    unreachable(); 
    break; 

ताकि सभी मामलों नियंत्रित किया जाएगा। आप इसे इतनी वर्बोज़ होने से रोकने के लिए एक मैक्रो बना सकते हैं।

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