gcc gives the warning when compiling the following code with -Wall: int main() { unsigned char b = '1'; bool x = ~b; return 0; } test.cpp:5: warning: comparison of promoted ~unsigned with constant g++ has the same behaviour. Release: gcc-3.2
From: Richard Earnshaw <rearnsha@arm.com> To: jozef.kosoru@pobox.sk Cc: gcc-gnats@gcc.gnu.org, Richard.Earnshaw@arm.com Subject: Re: c/8715: '~' operator for unsigned char and conversion to bool Date: Tue, 26 Nov 2002 17:45:54 +0000 > int main() > { > unsigned char b = '1'; > > bool x = ~b; > > return 0; > } > Which is equivalent to writing unsigned char b = 0x31; bool x = (~(int) b) != 0; which collapses to bool x = 1; > test.cpp:5: warning: comparison of promoted ~unsigned with constant A warning would probably seem appropriate. since no value of b can lead to the x being set to 0.
State-Changed-From-To: open->analyzed State-Changed-Why: Richard Earnshaw has already analyzed this. However, I concur with the submitter that the message as is is rather misleading.
Bogus message only appears for C++, not C.
(In reply to comment #3) > Bogus message only appears for C++, not C. > Not anymore. I get the warning for C with gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5) using -Wsign-compare (which is included in -Wextra). Is this really a bug?
(In reply to comment #1) > > Which is equivalent to writing > > unsigned char b = 0x31; > bool x = (~(int) b) != 0; > b being promoted to int is the expected behaviour or is it just what happens currently? I don't get why it is promoted... > A warning would probably seem appropriate. since no value of b can lead to > the x being set to 0. What is kind of weird since I would expect any value different from 0 to set x to false.
OK. I see now. This seems hard to fix, since it is exposing the current implementation of a conversion to bool.
(In reply to comment #6) > OK. I see now. This seems hard to fix, since it is exposing the current > implementation of a conversion to bool. > No, it's not the 'current implementation', its the way the C and C++ standards say this has to happen. When arithmetic operators are applied to sub-int sized operands they are first converted to int (or unsigned int if they can't be represented in int -- which is only the case when you have a machine where sizeof(unsigned short) == sizeof(unsigned int), or something similar).
(In reply to comment #7) > (In reply to comment #6) > > OK. I see now. This seems hard to fix, since it is exposing the current > > implementation of a conversion to bool. > > > > No, it's not the 'current implementation', its the way the C and C++ standards > say this has to happen. When arithmetic operators are applied to sub-int sized > operands they are first converted to int (or unsigned int if they can't be > represented in int -- which is only the case when you have a machine where > sizeof(unsigned short) == sizeof(unsigned int), or something similar). > I think I expressed myself badly. I meant that the warning is appropriate but the message is confusing because it is exposing that when doing bool x = ~b; we actually do bool x = (~b != 0); So an appropriate message would say something like: test.cpp:5: warning: '(bool) ~b' is always true But that is hard to achieve with the current implementation. Don't you agree?
(In reply to comment #8) > I meant that the warning is appropriate but > the message is confusing because it is exposing that when doing > > bool x = ~b; > > we actually do > > bool x = (~b != 0); > Or, more precisely, bool x = (~(int) b) != 0; > So an appropriate message would say something like: > > test.cpp:5: warning: '(bool) ~b' is always true > Don't you agree? > Yes, that would be nice, but hard to implement.
(In reply to comment #9) > (In reply to comment #8) > > I meant that the warning is appropriate but > > the message is confusing because it is exposing that when doing > > > > bool x = ~b; > > > > we actually do > > > > bool x = (~b != 0); > > > Or, more precisely, > bool x = (~(int) b) != 0; > > > So an appropriate message would say something like: > > > > test.cpp:5: warning: '(bool) ~b' is always true > > > Don't you agree? > > > > Yes, that would be nice, but hard to implement. > Isn't any way to tell that "!= 0" was introduced by GCC rather than by the original source code?
Subject: Bug 8715 Author: manu Date: Wed Aug 6 16:17:41 2008 New Revision: 138814 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138814 Log: 2008-08-06 Manuel Lopez-Ibanez <manu@gcc.gnu.org> PR 8715 * c-common.c (warn_for_sign_compare): New. Handle separately the case that 'constant' is zero. * c-typeck.c (build_binary_op): Move code to c-common.c cp/ * typeck.c (cp_build_binary_op): Move code to c-common.c. testsuite/ * gcc.dg/pr8715.c: New. * g++.dg/warn/pr8715.C: New. Added: trunk/gcc/testsuite/g++.dg/warn/pr8715.C trunk/gcc/testsuite/gcc.dg/pr8715.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-common.c trunk/gcc/c-common.h trunk/gcc/c-typeck.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog
Fixed in GCC 4.4.