c++booleaninteger-promotiontildelogical-or

C++ Tilde Operator on bool


I've done the LinkedIn C++ Assessment and got the following question:


What is the result from executing this code snippet?

bool x=true, x=false;

if(~x || y) {
    /*part A*/
}
else {
   /*part B*/
}

I don't know anymore what the answers were, but I thought "B" should be displayed, right?

I thought by "~", x is inverted ("bitwise NOT") and is therefore no longer "true"

But when I run the code, I get "A":

Code:

#include <iostream>

int main()
{

    bool x = true, y = false;

    std::cout << "x: " << x << std::endl;
    std::cout << "~x: " << ~x << std::endl;

    if (~x || y) {
        std::cout << "A" << std::endl;
    }
    else {
        std::cout << "B" << std::endl;
    }

    return 0;
}

Output:

x: 1
~x: -2
A

Can someone explain this to me?


Solution

  • In this expression

    ~x
    

    there is applied the integral promotions to the operand x of the type bool. The result of the promotion is an object of the type int that has the value equal to 1 like (in binary)

    00000000 00000000 00000000 00000001 
    

    The operator ~ inverses bits and you will get

    11111111 11111111 11111111 11111110
    

    From the C++ 14 Standard (5.3.1 Unary operators)

    10 The operand of ~ shall have integral or unscoped enumeration type; the result is the one’s complement of its operand. Integral promotions are performed. The type of the result is the type of the promoted operand.

    and (4.5 Integral promotions)

    6 A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

    7 These conversions are called integral promotions.

    As this value is not equal to 0 then used as an operand of the logical OR operator it is implicitly converted to the boolean value true.

    From the C Standard (5.15 Logical OR operator)

    1 The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.

    and (4.12 Boolean conversions)

    1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.