Unexpected behaviour using unsigned char in comparison

Axel Freyn axel-freyn@gmx.de
Sun Jan 9 18:21:00 GMT 2011


Hi Falk,
On Sun, Jan 09, 2011 at 07:00:04PM +0100, Falk S. wrote:
> Hi,
>
> in the following program the return value of the test2uc() function is  
> always false, however I would expect it to be true.
> #include <iostream>
> using namespace std;
>
> bool test2uc() {
>        typedef unsigned char uchar;
>        uchar mask = ~(uchar(0)) << 1;
>        return (mask | uchar(true)) == (~ uchar(0));
> }
>
> int main(int argc, char** args) {
>        cout << test2uc() << endl;
>        return 0;
> }
>
> Compiled with -ansi -Wall -g -gdwarf-2 -pedantic
> g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
> g++.exe (GCC) 4.5.0 (MingW)
> on Windows 7
>
> I get a "warning: comparison is always false due to limited range of  
> data type" when compiling with g++ a c++ file, which I do not understand.
> If I change the type of uchar to char, i.e. signed char, I get the  
> expected result.
The problem is that the operator "~" when applied upon the unsigned
char returns always a signed char. uchar(0) are 8 bits of "0",
"~uchar(0)" are 8 bits of "1" -- when interpreted as signed char, this
gives the value "-1". So effectively you check for "255 == -1", which is
false.

You can correct it by:
 - comparing the bits and not the "full" values, e.g. by using
   return  ( (mask | uchar(true)) xor uchar(~ uchar(0)) ) == 0; 
 - convert explicitely the right side to an unsigned value
   return (mask | uchar(true)) == uchar(~ uchar(0));

However, I'm not 100% sure what the C++-standard says to the question
(whether ~uchar(0) should be an signed or an unsigned integer...)

HTH,

Axel



More information about the Gcc-help mailing list