Why doesn't c++ have &&= or ||= for booleans?
A bool
may only be true
or false
in C++. As such, using &=
and |=
is relatively safe (even though I don’t particularly like the notation). True, they will perform bit operations rather than logical operations (and thus they won’t short-circuit) but these bit operations follow a well-defined mapping, which is effectively equivalent to the logical operations, as long as both operands are of type bool
.1
Contrary to what other people have said here, a bool
in C++ must never have a different value such as 2
. When assigning that value to a bool
, it will be converted to true
as per the standard.
The only way to get an invalid value into a bool
is by using reinterpret_cast
on pointers:
int i = 2;
bool b = *reinterpret_cast<bool*>(&i);
b |= true; // MAY yield 3 (but doesn’t on my PC!)
But since this code results in undefined behaviour anyway, we may safely ignore this potential problem in conforming C++ code.
1 Admittedly this is a rather big caveat as Angew’s comment illustrates:
bool b = true;
b &= 2; // yields `false`.
The reason is that b & 2
performs integer promotion such that the expression is then equivalent to static_cast<int>(b) & 2
, which results in 0
, which is then converted back into a bool
. So it’s true that the existence of an operator &&=
would improve type safety.
Do the &= and |= operators for bool short-circuit?
From C++11 5.17 Assignment and compound assignment operators
:
The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
However, you're mixing up logical AND which does short-circuit, and the bitwise AND which never does.
The text snippet &&=
, which would be how you would do what you're asking about, is nowhere to be found in the standard. The reason for that is that it doesn't actually exist: there is no logical-and-assignment operator.
&&= and ||= operators
I don't know why both the question and some of the answers mention short-circuiting behavior of the corresponding logical operators as a potential issue.
There's absolutely no short-circuit-related problems with defining &&=
and ||=
operators. They should be defined uniformly with +=
and other similar operators, meaning that a &&= b
should be equivalent to a = a && b
, but with a
being evaluated only once in &&=
version. This means in turn that b
is not evaluated at all if a
is originally zero. Easy.
So, the only reason they don't exist in the language is, well, "just because".
How does C++ handle &&? (Short-circuit evaluation)
Yes, the &&
operator in C++ uses short-circuit evaluation so that if bool1
evaluates to false
it doesn't bother evaluating bool2
.
"Short-circuit evaluation" is the fancy term that you want to Google and look for in indexes.
The same happens with the ||
operator, if bool1
evaluates to true
then the whole expression will evaluate to true, without evaluating bool2
.
In case you want to evaluate all expressions anyway you can use the &
and |
operators.
python augmented assignment for boolean operators
No, there is no augmented assignment operator for the boolean operators.
Augmented assignment exist to give mutable left-hand operands the chance to alter the object in-place, rather than create a new object. The boolean operators on the other hand cannot be translated to an in-place operation; for x = x and y
you either rebind x
to x
, or you rebind it to y
, but x
itself would not change.
As such, x and= y
would actually be quite confusing; either x
would be unchanged, or replaced by y
.
Unless you have actual boolean objects, do not use the &=
and |=
augmented assignments for the bitwise operators. Only for boolean objects (so True
and False
) are those operators overloaded to produce the same output as the and
and or
operators. For other types they'll either result in a TypeError
, or an entirely different operation is applied. For integers, that's a bitwise operation, sets overload it to do intersections.
How do I set, clear, and toggle a single bit?
Setting a bit
Use the bitwise OR operator (|
) to set a bit.
number |= 1UL << n;
That will set the n
th bit of number
. n
should be zero, if you want to set the 1
st bit and so on upto n-1
, if you want to set the n
th bit.
Use 1ULL
if number
is wider than unsigned long
; promotion of 1UL << n
doesn't happen until after evaluating 1UL << n
where it's undefined behaviour to shift by more than the width of a long
. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&
) to clear a bit.
number &= ~(1UL << n);
That will clear the n
th bit of number
. You must invert the bit string with the bitwise NOT operator (~
), then AND it.
Toggling a bit
The XOR operator (^
) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the n
th bit of number
.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the n
th bit of number
into the variable bit
.
Changing the nth bit to x
Setting the n
th bit to either 1
or 0
can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n
will be set if x
is 1
, and cleared if x
is 0
. If x
has some other value, you get garbage. x = !!x
will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1
has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
will clear the n
th bit and (x << n)
will set the n
th bit to x
.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
What does the construct x = x || y mean?
It means the title
argument is optional. So if you call the method with no arguments it will use a default value of "Error"
.
It's shorthand for writing:
if (!title) {
title = "Error";
}
This kind of shorthand trick with boolean expressions is common in Perl too. With the expression:
a OR b
it evaluates to true
if either a
or b
is true
. So if a
is true you don't need to check b
at all. This is called short-circuit boolean evaluation so:
var title = title || "Error";
basically checks if title
evaluates to false
. If it does, it "returns" "Error"
, otherwise it returns title
.
Related Topics
C++ Linking Error After Upgrading to MAC Os X 10.9/Xcode 5.0.1
Version 'Cxxabi_1.3.8' Not Found (Required by ...)
What Does _T Stands for in a Cstring
How to Have Polymorphic Containers with Value Semantics in C++
Differencebetween a .Cpp File and a .H File
How to Convert Rgb -> Yuv -> Rgb (Both Ways)
In Lambda Functions Syntax, What Purpose Does a 'Capture List' Serve
How to Get a Certain Element in a List, Given the Position
Is "Std::Cout" Usable in Android-Ndk
Inheriting Private Members in C++
How to Tell If a Lib Was Compiled with /Mt or /Md
Getting a Directory Name from a Filename
Multiple Inheritance + Virtual Function Mess
Delete All Items from a C++ Std::Vector
Class Template for Numeric Types