Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning about tautological compares inhibited by const?

The following piece of code generates warnings on both GCC and Clang:

int main() {
  unsigned n = 0;
  return ( n < 0 ) ? 1 : 0;
}

The warnings are:

$ g++-4.7 -std=c++11 -O3 -Wall -Wextra t.cc -o t
t.cc: In function ‘int main()’:
t.cc:3:16: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
$ clang++-3.2 -std=c++11 -O3 -Wall -Wextra t.cc -o t
t.cc:3:14: warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
  return ( n < 0 ) ? 1 : 0;
           ~ ^ ~
1 warning generated.
$ 

So far, so good. Now I change the variable to be const:

int main() {
  const unsigned n = 0;
  return ( n < 0 ) ? 1 : 0;
}

And both compilers are suddenly happy to compile the code without warnings:

$ g++-4.7 -std=c++11 -O3 -Wall -Wextra t.cc -o t
$ clang++-3.2 -std=c++11 -O3 -Wall -Wextra t.cc -o t
$ 

QUESTION: Why does this happen? Is there a reason, why const variables suppress the warning? If both GCC and Clang agree, I hesitate to just throw a bug-report at them as it seems more likely that I need to learn something :)

EDIT: The constant folding of the compiler might have to do with it, but it is not sufficient to explain the behaviour. In the first example (without the const), the compiler does know the value and that it never changes. I checked the assembler output and the compiler does do constant folding but it still generates the warning, probably before it replaces the variable by the known constant when it sees the expression ( n < 0 ) and knowing that n is an unsigned type. That said: Why does this behaviour changes when I add const? I think that if the first example produces a warning, it should also be possible to generate a warning for the second.

like image 453
Daniel Frey Avatar asked Mar 02 '13 10:03

Daniel Frey


1 Answers

It's an explicit constant -- your intent. Your desired warning is effectively transferred from:

warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
return ( n < 0 ) ? 1 : 0;
         ~ ^ ~

to -Wunreachable-code when const:

warning: will never be executed [-Wunreachable-code]
return ( n < 0 ) ? 1 : 0;
                   ^

Note: -Wtautological-compare warnings may still be emitted by the compiler where values are not known.

like image 185
justin Avatar answered Oct 06 '22 23:10

justin