19

I have written this C++ program, and I am not able to understand why it is printing 1 in the third cout statement.

#include<iostream>

using namespace std;

int main()
{
    bool b = false;
    cout << b << "\n";  // Print 0
    b = ~b;
    cout << b << "\n"; // Print 1
    b = ~b;
    cout << b << "\n"; // Print 1 **Why?**
    return 0;
}

Output:

0
1
1

Why is it not printing the following?

0
1
0
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vikiiii
  • 9,246
  • 9
  • 49
  • 68
  • 6
    Really dont know why someone voting to close. – vikiiii Jun 17 '13 at 13:39
  • 1
    +1 @vikiiii - Unfortunately, downvoting and voting to close are the weak points of stackexchange, I believe because they happen in an anonymous manner. – Sabuncu Jun 17 '13 at 17:52
  • 1
    So you basically use the wrong operator and wondering why it gives you not what you expected? – szx Jun 18 '13 at 06:33

4 Answers4

26

This is due to C legacy operator mechanization (also recalling that ~ is bitwise complement). Integral operands to ~ are promoted to int before doing the operation, then converted back to bool. So effectively what you're getting is (using unsigned 32 bit representation) false -> 0 -> 0xFFFFFFFF -> true. Then true -> 1 -> 0xFFFFFFFE -> 1 -> true.

You're looking for the ! operator to invert a boolean value.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 9
    Because false is represented as `0x0000` using unsigned int, while true can be anything else. – JBL Jun 17 '13 at 13:56
7

You probably want to do this:

b = !b;

which is logical negation. What you did is bitwise negation of a bool cast to an integer. The second time the statement b = ~b; is executed, the prior value of b is true. Cast to an integer this gives 1 whose bitwise complement is -2 and hence cast back to bool true. Therefore, true values of b will remain true while false values will be assigned true. This is due to the C legacy.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
7

As pretty much everyone else has said, the bool is getting promoted to an integer before the complement operator is getting its work done. ~ is a bitwise operator and thus inverts each individual bit of the integer; if you apply ~ to 00000001, the result is 11111110. When you apply this to a 32-bit signed integer, ~1 gives you -2. If you're confused why, just take a look at a binary converter. For example: http://www.binaryconvert.com/result_signed_int.html?decimal=045050

To your revised question:

False to true works for the same reason as above. If you flip 00000000 (out to 32 bits), you get 11111111... which I believe is -1 in integer. When comparing boolean values, anything that is -not- 0 is considered to be true, while 0 alone is false.

cmark89
  • 247
  • 2
  • 9
2

You should use logical operators, not binary operators. Use ! instead of ~.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Darkoob12
  • 114
  • 2
  • 8