Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using bitwise operators for Booleans in C++

Is there any reason not to use the bitwise operators &, |, and ^ for "bool" values in C++?

I sometimes run into situations where I want exactly one of two conditions to be true (XOR), so I just throw the ^ operator into a conditional expression. I also sometimes want all parts of a condition to be evaluated whether the result is true or not (rather than short-circuiting), so I use & and |. I also need to accumulate Boolean values sometimes, and &= and |= can be quite useful.

I've gotten a few raised eyebrows when doing this, but the code is still meaningful and cleaner than it would be otherwise. Is there any reason NOT to use these for bools? Are there any modern compilers that give bad results for this?

like image 356
Jay Conrod Avatar asked Aug 23 '08 19:08

Jay Conrod


People also ask

Can you use bitwise operators on Booleans?

Using bitwise operations for bool helps save unnecessary branch prediction logic by the processor, resulting from a 'cmp' instruction brought in by logical operations. Replacing the logical with bitwise operations (where all operands are bool) generates more efficient code offering the same result.

Can you do bitwise operations in C?

In the C programming language, operations can be performed on a bit level using bitwise operators. Bitwise operations are contrasted by byte-level operations which characterize the bitwise operators' logical counterparts, the AND, OR, NOT operators.

Where bitwise operators are used in C?

The Bitwise Operator in C is a type of operator that operates on bit arrays, bit strings, and tweaking binary values with individual bits at the bit level. For handling electronics and IoT-related operations, programmers use bitwise operators. It can operate faster at a bit level.

Is && A bitwise operator?

A Bitwise And operator is represented as '&' and a logical operator is represented as '&&'. The following are some basic differences between the two operators. a) The logical and operator '&&' expects its operands to be boolean expressions (either 1 or 0) and returns a boolean value.


2 Answers

|| and && are boolean operators and the built-in ones are guaranteed to return either true or false. Nothing else.

|, & and ^ are bitwise operators. When the domain of numbers you operate on is just 1 and 0, then they are exactly the same, but in cases where your booleans are not strictly 1 and 0 – as is the case with the C language – you may end up with some behavior you didn't want. For instance:

BOOL two = 2; BOOL one = 1; BOOL and = two & one;   //and = 0 BOOL cand = two && one; //cand = 1 

In C++, however, the bool type is guaranteed to be only either a true or a false (which convert implicitly to respectively 1 and 0), so it's less of a worry from this stance, but the fact that people aren't used to seeing such things in code makes a good argument for not doing it. Just say b = b && x and be done with it.

like image 107
Patrick Avatar answered Oct 12 '22 12:10

Patrick


Two main reasons. In short, consider carefully; there could be a good reason for it, but if there is be VERY explicit in your comments because it can be brittle and, as you say yourself, people aren't generally used to seeing code like this.

Bitwise xor != Logical xor (except for 0 and 1)

Firstly, if you are operating on values other than false and true (or 0 and 1, as integers), the ^ operator can introduce behavior not equivalent to a logical xor. For example:

int one = 1; int two = 2;  // bitwise xor if (one ^ two) {   // executes because expression = 3 and any non-zero integer evaluates to true }  // logical xor; more correctly would be coded as //   if (bool(one) != bool(two)) // but spelled out to be explicit in the context of the problem if ((one && !two) || (!one && two)) {   // does not execute b/c expression = ((true && false) || (false && true))   // which evaluates to false } 

Credit to user @Patrick for expressing this first.

Order of operations

Second, |, &, and ^, as bitwise operators, do not short-circuit. In addition, multiple bitwise operators chained together in a single statement -- even with explicit parentheses -- can be reordered by optimizing compilers, because all 3 operations are normally commutative. This is important if the order of the operations matters.

In other words

bool result = true; result = result && a() && b(); // will not call a() if result false, will not call b() if result or a() false 

will not always give the same result (or end state) as

bool result = true; result &= (a() & b()); // a() and b() both will be called, but not necessarily in that order in an // optimizing compiler 

This is especially important because you may not control methods a() and b(), or somebody else may come along and change them later not understanding the dependency, and cause a nasty (and often release-build only) bug.

like image 30
Patrick Johnmeyer Avatar answered Oct 12 '22 10:10

Patrick Johnmeyer