Генерирует ли-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/S9XE3d

Этот случай наиболее интересен: https://godbolt.org/g/TDUhN7

Вы можете подумать, что вы проверили против незаконных значений. Но компилятор удалил код:)

Кстати - интересно, почему мой ответ был отклонен

Другие вопросы по тегам