Unexpected behaviour using unsigned char in comparison
Falk S.
falk-o-mat@gmx.de
Sun Jan 9 19:24:00 GMT 2011
Axel Freyn wrote:
> 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.
>
Thanks for the explanation. Is this a gcc-specific behaviour?
> 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...)
>
Ok, that would be the "unexpected". I thought the unary operator~ needs
no conversion (promotion) and therefore the return type is the same as
the argument type.
bye,
Falk
More information about the Gcc-help
mailing list