Генерирует ли-Gma's -Wmaybe неинициализированное ложное предупреждение с -O1 для оператора switch на основе перечисления?
У меня есть кусок кода следующей формы:
typedef enum {A=1,B} EnumType;
int foo (EnumType x)
{
int r;
switch (x) {
case A:
r = 1;
break;
case B:
r = 2;
break;
/*
default:
r = -1;
break;
*/
}
return r;
}
Я компилирую с GCC 6.3.0 и получаю предупреждение:
$ gcc --version
gcc (MacPorts gcc6 6.3.0_2) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -c -Wall -O1 test.c
test.c: In function 'foo':
test.c:20:10: warning: 'r' may be used uninitialized in this function [-Wmaybe-uninitialized]
return r;
^
Код кажется мне безопасным, и действительно есть некоторое обсуждение GCC, производящего ложные срабатывания с этим предупреждением.
Это ложное предупреждение?
Более актуальная информация:
- Добавление закомментированного
default:
блок разрешает предупреждение - Предупреждение не появляется с
-O0
2 ответа
Это предупреждение совершенно правильно, потому что enum
Тип не ограничивает возможные значения членами, определенными в этом enum
вместо этого он может содержать любое значение базового целочисленного типа. Так что без default
ветка в вашем коммутаторе, вы действительно можете использовать r
неинициализирован с кодом, который вы показываете.
Я могу воспроизвести предупреждение, отсутствующее с gcc
а также -O0
с точным кодом, показанным в вопросе, так что это выглядит для меня как ошибка в gcc
, Предупреждение должно быть дано независимо от уровня оптимизации.
Это легко понять: есть возможные пути к программам, где r будет возвращено неинициализированным. Итак, вы получили предупреждение. Enum - просто int, поэтому у вас есть много возможных случаев.
Перечисления не проверяются временем выполнения по значениям.
О второй части вопроса. Это преднамеренно, как может любой уровень оптимизации (и в этом случае код будет удален, если значения типа enum недопустимы - компилятор предполагает, что другие значения невозможны)
Этот случай наиболее интересен: https://godbolt.org/g/TDUhN7
Вы можете подумать, что вы проверили против незаконных значений. Но компилятор удалил код:)
Кстати - интересно, почему мой ответ был отклонен