2017-02-20 26 views
3

Если я составляю следующую простую программу (test.c) с помощью лязгалязга тавтологические константные вне диапазона Сравните предупреждение

#include <stdio.h> 

typedef enum { 
    a, 
    b 
} sample_enum_t; 


int main() { 
    sample_enum_t sample_enum = -1; 
    if (sample_enum == -1) { 
     printf("Equals\n"); 
    } 
} 

В компилирует дает мне предупреждение:

$ clang -o test test.c 
test.c:11:21: warning: comparison of constant -1 with expression of type 'sample_enum_t' is always false [-Wtautological-constant-out-of-range-compare] 
    if (sample_enum == -1) { 
     ~~~~~~~~~~~^~~ 
1 warning generated. 

это явно не соответствует действительности, что сравнение всегда ложно, если я выполнить программу печатает в «Равно»:

$ ./test 
Equals 

ли лязг ошибка, или я чего-то не хватает? Я понимаю, что назначение -1 переменной sample_enum не очень хорошая идея, но это допустимая строка, и clang не дает мне предупреждения из-за этой строки.

Я использую лязг 3.5.2

+1

[Эта проблема с Кланом кажется актуальной] (https://bugs.llvm.org//show_bug.cgi?id=16154). Он не закрыт, поэтому я не уверен, что он был рассмотрен. Я понимаю, что они считают это полезным предупреждением, но его следует переформулировать, чтобы люди не могли удалять код, основанный на предупреждении. – unwind

+0

Ouch, что bugreport 3,5 лет. – asalamon74

ответ

1

Игнорирование Clang является ли правильным или неправильным на данный момент, давайте посмотрим на то, что говорит стандарт.

6.7.2.2 Enumeration specifiers:

Каждый перечислимого типа, должны быть совместимы с полукокса, подписанную целого типа, или без знака целого типа. Выбор типа определяется реализацией, 128), но должен быть способен представлять значения всех членов перечисления. Перечисленный тип является неполным, пока сразу после {}, который завершает список деклараций перечислителя и завершается после этого.

128) Реализация может задержать выбор целочисленного типа до тех пор, пока не будут видны все константы перечисления.

Вы полагаетесь на , определяемый реализацией поведение; может ли тип, выбранный вами в реализации, представлять -1, не определен стандартом. И Clang, и GCC используют unsigned int (в моем тестировании для вашего кода с использованием gcc 7.0.1 и clang 3.8.0). Таким образом, ваш код действителен, поскольку нет проблемы, представляющей -1.

Итак, это не настоящая проблема, и диагностика Клана несколько полезна, поскольку если вы случайно использовали какое-то значение вне диапазона констант перечисления, которые вы определили.