Search code examples
c++booleanboolean-expressionboolean-operations

Why ~(true^true) is not true? Boolean operators (negation) works for `unsigned char`s, but not for bools? (C++)


I heard that often "everything" besides 0 is true. But now very strange things are happening to me... or I just think that I do it in correct way while I don't. Here's what is happening:

When I want to check if a is equivalent b, I can use NOT(a XOR b). When I checked it for unsigned char's, everything was ok, for example

unsigned char a = 5;
unsigned char b = 3;
unsigned char c = ~(a^b);

gave me c == 249:

a is: 00000101, which is 5.

b is: 00000011, which is 3.

~(a^b) is: 11111001, which is 249.

Now, let's try this with bool's.

cout << ~(true^true) << ~(true^false) << ~(false^true) << ~(false^false) << endl;
cout << ~(~(true^true)) << ~(~(true^false)) << ~(~(false^true)) << ~(~(false^false)) << endl;

if (~(true^true) == true)
    cout << "true";
else
    cout << "false";

This gives me in console:

-1-2-2-1
0110
false

while I expected the first line to be:

1001

After asking a friend, he advised me to try ! instead of ~ and see if it will work correctly. And (I think) it works correctly now. But I don't understand why. Shouldn't boolean negation work for bools?


Solution

  • I heard that often "everything" besides 0 is true

    It is valid for conditions as for example in the if statement (here and below I am citing the C++Standard)

    The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch

    For example if you would write as

    if (~(true^true) )
        cout << "true";
    else
        cout << "false";
    

    instead of your code snippet

    if (~(true^true) == true)
        cout << "true";
    else
        cout << "false";
    

    or when the logical negation operator ! is used

    9 The operand of the logical negation operator ! is contextually converted to bool (Clause 4); its value is true if the converted operand is false and false otherwise. The type of the result is bool

    As for operator == then

    6 If both operands are of arithmetic or enumeration type, the usual arithmetic conversions are performed on both operands; each of the operators shall yield true if the specified relationship is true and false if it is false.

    That is in case of

    if (~(true^true) == true)
    

    the usual arithmetic conversion is applied that is boolean value true is converted to integer value 1 and it is not equal to the expression of the left operanf because internal binary representation of the left operand differs from 1 as showed the output of your first code snippet..