Ответ 1
Вы не указали, какой компилятор вы используете. Если вы используете GCC, вы можете получить это бесплатно, просто включив -Wswitch
(который автоматически включается -Wall
).
Я хотел бы получить предупреждение или ошибку компилятора, когда не все возможные значения перечисления обрабатываются в инструкции switch. Конечно, я могу добавить случай по умолчанию с утверждением и (в конечном итоге) получить ошибку во время выполнения. Но я бы хотел получить ошибку во время компиляции.
Я не уверен, что это вообще возможно с С++, но, возможно, кто-то знает трюк...
Изменить:
Использование -Wswitch
представляется решением для GCC. Есть ли что-то подобное для VS2010? (Я не использую GCC).
Edit2: Хорошо, я нашел решение для VС++ (VS2010):
Включение предупреждения C4062
выдает предупреждение, когда значение отсутствует, и не предоставляется случай по умолчанию.
Включение предупреждения C4061
выдает предупреждение, когда значение отсутствует, даже если предусмотрен случай по умолчанию.
Вы не указали, какой компилятор вы используете. Если вы используете GCC, вы можете получить это бесплатно, просто включив -Wswitch
(который автоматически включается -Wall
).
Если вы используете g++, с -Wall
, вы получите его.
Например, это:
enum Abc
{
A =1,
B,
C
};
Abc a = A;
switch( a )
{
case A:
break;
case B:
break;
}
будет вызывать предупреждение.
Но лучше использовать аргумент default
с неудачным утверждением, потому что когда вы добавляете новое значение enum, вы должны изменить все файлы, в которых вы используете переключатель на этом перечислении.
AFAIK нет обычного способа добиться того, что вы хотите с помощью MSVC. Есть трюки, чтобы делать подобные вещи, но они включают либо сложный шаблон voodoo, либо действительно жестокие макросы загадок.
Например, вместо определения вашего перечисления обычным способом выполните следующие действия:
#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;
}
Вышеуказанное не будет компилироваться, если вы не добавите запись переключателя label_...
для всех значений перечисления.
g++ делает это автоматически, если вы включаете все предупреждения с помощью -Wall
.