Подтвердить что ты не робот

Почему "typeof enum constant" генерирует предупреждение по сравнению с переменной типа enum?

У меня есть следующий код.

typedef enum {FOO, BAR} Baz;

int main()
{
    Baz f1 = FOO;
    typeof(FOO) f2 = FOO;
    return (f1 == f2);
}

Моя компиляция с помощью gcc -Wextra foo.c генерирует предупреждение

foo.c: In function ‘main’:
foo.c:7:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 return (f1 == f2);
             ^

Моя версия gcc

gcc --version
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2

Как я могу исправить эту проблему?

4b9b3361

Ответ 1

Цитирование непосредственно из C11, главы §6.7.2.2, Спецификаторы перечисления,

Каждый перечисленный тип должен быть совместим с char, целочисленным типом со знаком или беззнаковым целым типом. Выбор типа определяется реализацией.

Таким образом, тип переменной перечисления не определяется стандартом. Это может быть любой из вышеперечисленных.

OTOH, FOO является константой перечисления, typeof(FOO) даст вам int, поскольку стандартные мандаты

Идентификатор, объявленный как константа перечисления, имеет тип int.

который используется как тип для f2.

Теперь, если перечисление unsigned int в вашей реализации, то есть f1 и f2 int.

Затем вы получите предупреждение.

Как я могу исправить эту проблему?

Ну, если вы измените тип f2 на typeof(Baz), который задает тип перечисления, то оба типа f1 и f2 будут одинаковыми. Компилятор будет счастлив.

СМОТРИТЕ ЗДЕСЬ

Ответ 2

Это известная "ошибка" в стандарте C. Константы перечисления гарантированно имеют тип int, в то время как переменные перечисления имеют целочисленный тип, определенный реализацией.

См. это для справок.