I ran across some code today that was checking a number of error conditions. A single boolean was used all the way through, but instead of reassigning it every time with an =, it was reassigned with an &= resulting in a bit wise ANDing of the the previous value of the boolean and the new value. The code looked something like this:

bool result = FirstCheck();
Assert(result);
result &= SecondCheck();
Assert(result);
...

Now I'm curious why someone would do this? This is logically equivalent to just reassigning the value of the boolean as shown by the possible branches below:

  1. FirstCheck fails (returns false) and program fails on assert and never makes it to SecondCheck
  2. FirstCheck passes (returns true) and the program makes it to SecondCheck. If SecondCheck returns true, then result is true because true&true = true. If SecondCheck returns false, then result is false becasue true&false = false.

Since there is no logical difference, is there some other reason &= might be preferable? Or is it more likely that is is a relic of some old code that just never got changed?

EDIT: To clarify, the Assert is always active code. I actually stumbled across this code while investigating a bug because the assert was failing.

有帮助吗?

解决方案 2

I guess that on the beginning it was:

bool result = FirstCheck();
result &= SecondCheck();
Assert(result);

so the code was checking that both results were positive, but then somebody added the Assert() after the firstCheck().

Or the person might be from C++ background and thought that bitwise operators are faster than logical ones.

其他提示

Yes, the reason is that you use a single bool to accumulate the return codes for multiple functions.

Without the &= you overwrite the return code with the latest function on every call, therefore you only ever test whether the last function was successful. With &= if a single function returns false then the return code remains false from that point onwards, so you know that at least one function failed.

It saves writing code like this

bFirstCheck == fn1();
bSecondCheck == fn2();
bThirdCheck == fn3();

if (bFirstCheck && bSecondCheck && bThirdCheck) {
}

When you can write code like:

bCheck = fn1();
bCheck &= fn2();
bCheck &= fn3();

if (true == bCheck) {
}

You're assuming the assertions are enabled. If this is using Debug.Assert, the method will only actually be called if the DEBUG conditional compilation symbol is defined.

Assuming result is used later on (beyond the assertion) then there's a difference when FirstCheck() returns false.

Like the others said, Assert might not always be active code. Then let's assume that first and third check return true and second check returns false. Thus if you had

x = FirstCheck()
x = SecondCheck()
x = ThirdCheck()

then x would equal true.

But, if you did

x &= FirstCheck()
x &= SecondCheck()
x &= ThirdCheck()

x would equal false

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top