views:

396

answers:

4

In C++ it's possible to use a logical operator where a biwise operator was intended:

int unmasked = getUnmasked(); //some wide value
int masked = unmasked & 0xFF; // izolate lowest 8 bits

the second statement could be easily mistyped:

int masked = unmasked && 0xFF; //&& used instead of &

This will cause incorrect behaviour - masked will now be either 0 or 1 when it is inteded to be from 0 to 255. And C++ will not ever complain.

Is is possible to design code in such a way that such errors are detected at compiler level?

+2  A: 

Both operators represent valid operations on integers, so I don't see any way of detecting a problem. How is the compiler supposed to know which operation you really wanted?

anon
+3  A: 

This is a bit Captain Obvious, but you could of course apply encapsulation and just hide the bitmask inside a class. Then you can use operator overloading to make sure that the boolean operator&&() as you see fit.

I guess that a decent implementation of such a "safe mask" need not be overly expensive performance-wise, either.

unwind
+3  A: 

Ban in your coding standards the direct use of any bitwise operations in an arbitrary part of the code. Make it mandatory to call a function instead.

So instead of:

int masked = unmasked & 0xFF; // izolate lowest 8 bits

You write:

int masked = GetLowestByte(unmasked);

As a bonus, you'll get a code base which doesn't have dozens of error prone bitwise operations spread all over it.

Only in one place (the implementation of GetLowestByte and its sisters) you'll have the actual bitwise operations. Then you can read these lines two or three times to see if you blew it. Even better, you can unit test that part.

Daniel Daranas
I wouldn't want to work in a place that doesn't allow me to use a legitimate part of the language I'm writing in.
shoosh
@shoosh: (1) I just posted a possible strategy to solve the problem. (2) I'm not banning, I'm just moving these operations to a specific part (naturally, it would be a class).
Daniel Daranas
The whole idea looks quite reasonable for code where bitwise operators are used often and together with logical operators.
sharptooth
+2  A: 

In some instances you might get a compiler warning (I wouldn't expect one in your example though). A tool like lint might be able to spot possible mistakes.

I think the only way to be sure is to define your coding standards to make the difference between the two operators more obvious - something like:

template<typename T>
T BitwiseAnd( T value, T mask ) { return value & mask; }

and ban the bitwise operators & and |

markh44