Zróbmy listę wartości (foo.lst):uniknąć fałszywie dodatnie -Wswitch ostrzeżenia
foo,
bar,
baz,
Zróbmy enum z tym
enum foo {
#include "foo.lst"
_foo_length
};
Użyjmy tego wyliczenia w sposób switch
:
int main(void) {
enum foo[_foo_length];
switch(f[0]) {
case foo: return 0;
case bar: return 0;
case baz: return 0;
}
__builtin_unreachable();
}
(kod ten jest głupi, ale po prostu zignorować)
Problem:
Z -Wswitch
(wliczone w -Wall
), GCC i Clang (i prawdopodobnie innych) ostrzega:
ostrzegawczy: wartość wyliczenia '_foo_length' nie obsługiwane w przełączniku [-Wswitch]
Solutions:
- Wyłączenie
-Wno-switch
ukrywa, że ostrzeżenie.
Wada: tracimy ostrzeżenia o innych brakującychcase
w przełączniku. - Dodawanie obudowy
default: unreachable();
.
Wada: tracimy ostrzeżenia o zaginionych kompilacjach, na wypadek awarii środowiska wykonawczego, jeśli kiedykolwiek natrafimy na jeden z brakujących przypadków podczas debugowania. - Zastępowanie ostatniej wartości wyliczenia za pomocą
#define _foo_length (baz + 1)
, dzięki czemu nie jest już częścią wyliczenia.
Minus: wymaga ręcznego aktualizowania definicji za każdym razem, gdy wartość zostanie dodana do listy. Ktoś zawsze zapomni, łamie wszystko.
Idealnie, nie powinno być sposobem na oznaczyć wartość enum jako Żadna istota przypisywana, a tym samym nie wytwarzają ostrzeżenie kompilatora podczas czytania możliwe wartości i ten nie ma, bez konieczności makro preprocesora wymagające zduplikowanych modyfikacji.
Czy jest coś takiego? Jakieś inne opcje, o których nie myślałem?
Ponieważ dynamicznie tworzysz enum, jak możesz być pewien, że 'switch' naprawdę obejmuje wszystkie przypadki? – Barmar
A co się stanie, jeśli plik nie ma jednego z przypadków? Cała ta sprawa źle mnie pachnie. – Barmar
Możesz dodać 'case _foo_length:' – Barmar