Monday, November 26, 2012

... and that's the way it is!

One of the errors reported by Coverity on our code was this:
Logical vs. bitwise operator (CONSTANT_EXPRESSION_RESULT)
~sense is always 1/true regardless of the values of its operand. This occurs as the bool operand of assignment. Did you intend to use '!' rather than '~'


The code it referred to was something like:

bool sense;
...
if(~sense)
...


Note: If we write:
bool result = ~sense;
instead, we get the same result and same error.

Now this was quite surprising. The size of bool is 1-bit, and for years now, we have understood that though it is not a good practice to use bit-negation instead of logical negation for a one-bit quantity, the result is same (it's obviously wrong for multi-bit).
Refusing to believe coverity, we wrote a small CPP code:
======================

  bool sense = true;

  cout << "Size: " << sizeof(sense) << endl;

  if(~sense)
    cout << "Always true" << endl;
  else
    cout << "Can be false" << endl;

  bool result = ~sense;
  if(result)
    cout << "Always true" << endl;
  else
    cout << "Can be false" << endl;


======================
 


The result was totally unexpected, and stumped three of us who saw it:

Size: 1
Always true
Always true


Of course, any variable will be aligned to the word (8-bit boundary), but we expected any 0-padding to take place after the negation operation, and not before.

Our understanding that the bit-negation and logical negation yield same result for single bit, has perhaps resulted from years of conditioning of wroking with Verilog. It appears that C/C++ does not work that way. and we just have to accept it.