Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MonoDevelop suggests turning if statements into bitwise operations

MonoDevelop suggests turning this:

if (someBoolVar)
    anotherBoolVar = true;

into this:

anotherBoolVar |= someBoolVar;

It also does it when I set anotherBoolVar to false instead:

if (someBoolVar)
    anotherBoolVar = false;

becomes:

anotherBoolVar &= !someBoolVar;

Can someone explain how these statements are equal?

like image 733
foxneSs Avatar asked Mar 26 '15 13:03

foxneSs


4 Answers

Well, functionally they're equivalent.

In the first case you want to set anotherBoolVar to true if someBoolVar is true, regardless of what value anotherBoolVar currently has, the replacement expression does that.

It is short for this:

anotherBoolVar = anotherBoolVar | someBoolVar;

The second replacement also does the same as the code it replaces, and is short for this:

anotherBoolVar = anotherBoolVar & (!someBoolVar);

The solution is hidden in the "bitwise" nature of boolean variables in this case. To and with an inverted value (~ inverts the someBoolVar) will effectively say "keep all bits that are set in !someBoolVar and clear out the rest", meaning that if someBoolVar is true, it will be inverted to false, and you'll effectively clear out anotherBoolVar.


Now, should you do this ?

In my opinion, no. The code is more readable as-is. Keep, and possibly even look for a way to ask MonoDevelop to not suggest these things in the future.

like image 57
Lasse V. Karlsen Avatar answered Nov 01 '22 10:11

Lasse V. Karlsen


IDE code recommendations are often a double edge sword. Yes, the statements are terser BUT they are also potentially confusing (hence your pondering).

if (someBoolVar)
    anotherBoolVar = someBoolVar;

is the same as

anotherBoolVar |= someBoolVar;

because |= short-circuts if someBoolVar is false. If someBoolVar is true then it does not short-circut and therefore assigns the someBoolVar value (true) to anotherBoolVar.

Although the more terse statement may be slightly optimized I recommend you stick with your if statement because it is more expressive and readible.

For these type of if statements I try to keep them on one line:

if (someBoolVar) anotherBoolVar = someBoolVar;

like image 40
kingdango Avatar answered Nov 01 '22 12:11

kingdango


For e.g.

if (someBoolVar)
    anotherBoolVar = true;

So when someBoolVar is true it comes down to

anotherBoolVar = (whatever boolean value of anotherBoolVar) | true;

which will always evaluate to true.

like image 25
Nikhil Agrawal Avatar answered Nov 01 '22 11:11

Nikhil Agrawal


For the first change, the if construction means:

someBoolVar is true ==> anotherBoolVar becomes true
someBoolVar is false ==> anotherBoolVar is unchanged

The |= construction means:

someBoolVar is true ==> anotherBoolVar becomes (true | initial value) which is always true
someBoolVar is false ==> anotherBoolVar becomes (false | initial value) which is always equal to the initial value

Similar remarks apply to the second change, although as @Lasse V. Karlsen mentioned, the &= construction seems to be missing a tilde.

like image 28
Ross Presser Avatar answered Nov 01 '22 11:11

Ross Presser