Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clang tautological-constant-out-of-range-compare warning

If I compile the following simple program (test.c) using clang

#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");
    }
}

The compiles gives me a warning:

$ 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.

It is clearly not true that the comparison is always false, if I execute the program it prints at "Equals":

$ ./test 
Equals

Is it a clang bug or I'm missing something? I do understand that assigning -1 to the sample_enum variable is not a very good idea, but it's a valid line and clang does not give me a warning because of that line.

I'm using clang 3.5.2

like image 815
asalamon74 Avatar asked Feb 20 '17 12:02

asalamon74


1 Answers

Ignoring whether Clang is right or wrong for the moment, let's look at what the standard says.

6.7.2.2 Enumeration specifiers:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,128) but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.

128) An implementation may delay the choice of which integer type until all enumeration constants have been seen.

You are relying on implementation-defined behaviour; whether the type your implementation chooses can represent -1 isn't defined by the standard. Both Clang and GCC use unsigned int (in my testing for your code using gcc 7.0.1 and clang 3.8.0). So, your code is valid as there's no issue representing -1.

So, this is not a real issue and Clang's diagnostic is somewhat useful, in that if you have unintentionally used some value outside the range of enum constants you have defined.

like image 55
P.P Avatar answered Nov 15 '22 12:11

P.P