Reputation: 73081
If a C++ program applies the bitwise-not operator (~) to a boolean value, does that invoke Undefined Behavior?
E.g. is the following program well-defined?
bool f = false;
bool f2 = ~f; // is f2 guaranteed to be true, or is this UB?
bool t = true;
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB?
(Yes, I know there is a ! operator that is better-suited to this sort of thing; for purposes of this question we will ignore its existence ;))
Upvotes: 11
Views: 848
Reputation: 49289
bool t = true;
bool t2 = ~t; // is t2 guaranteed to be false, or is this UB?
I suppose it is not guaranteed, seeing how
bool b = true;
bool b1 = ~b;
cout << b1;
outputs a "true"
I suppose it has to do with boolean representation... if it is a byte, then 00000001
will negate to 11111110
which is not zero. Promotion might also be at play, but it's the same tune.
The key here is it is "bitwise" not "logical". So one should not expect the two to match, unless the boolean representation is a single bit.
Easily entirely defined behavior.
Upvotes: 1
Reputation: 52471
5.3.1/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. [emphasis mine]4.5/6 A prvalue of type
bool
can be converted to a prvalue of typeint
, withfalse
becoming zero andtrue
becoming one.4.5/7 These conversions are called integral promotions.
So ~false
is an int
with a bit pattern consisting of all ones - one's complement of a bit pattern representing 0, namely all zeros (as required by 3.9.1/7.) Similarly, ~true
is an int
that's one's complement of the bit representation of 1 - namely, all ones with the least significant bit zero. Both these values will evaluate to true
in boolean context.
Upvotes: 8
Reputation: 141598
The arithmetic operators perform the integral promotions on their operand. Specifically [expr.unary.op]/9 says that this happens for ~
too.
So ~t
is the same as ~1
. This gives a valid non-zero integer.
Integer-to-bool conversions are defined by [conv.bool]:
A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true
so bool t2 = ~t;
yields t2 == true
. There is no undefined behaviour.
~f
is the same as ~0
. In 2's complement, ~0
gives -1
, so we will have f2 == true
.
In 1's complement -- if there were ever a C++ system that uses 1's complement -- then the effect of ~0
is unclear.
Upvotes: 3