Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can this C/C++ if() statement ever evaluate to TRUE?

According to PC-lint, the following statement will never be TRUE:

if((variable & 0x02) == 1)

I am using a C compiler for embedded systems that evaluates it to TRUE whenever the corresponding bit in variable is set. I guess the compiler is doing a TRUE/FALSE comparison of both sides of the == instead of comparing the resulting numbers. In other words, every time the expression (varable & 0x02) is not zero (i.e. TRUE), the statement will also be TRUE, since the value 1 is also TRUE (not zero).

I don't know if the C/C++ standards clearly define how a compiler should behave in this case. Are there any C/C++ experts out there who can answer this question based on what the standards (e.g. C90, C99, etc.) say?

P.S.: In the statement above, "variable" is an unsigned char.

like image 768
Paraense Avatar asked Nov 11 '11 07:11

Paraense


3 Answers

PC-lint is right. Assuming var is an integer variable, the expression var & 0x02 can evaluate to two values: 0 and 2. It will never be equal to 1, which is what the if statement is testing.

To expand on this, the equality operator is being applied to two integer values. What matters is whether both operands evaluate to the same number, not whether they're both simultaneously "true" or "false".

To test whether bit 1 is set, one could use:

if (variable & 0x02) {
  ...
}

Given that your compiler behaves the way you say it does, it's clearly non-compliant. However, it will almost certainly handle if (variable & 0x02) correctly. My recommendation would be to fix the code so it won't break silently if you were ever to change compilers.

Finally, the situation is different if: (1) the code is C++ and not C; and (2) variable is instance of a class; and (3) the class overloads the operators in question. In that case, the behaviour is down to what the overloaded operators actually do.

like image 124
NPE Avatar answered Oct 31 '22 13:10

NPE


In C++, this can evaluate to a true value if (and only if) variable is an instance of a class with an overloaded operator& which does not conform to normal bitwise AND semantics.

In C, this condition will always be false. §6.5.10 defines the semantics of the bitwise AND operator, and it's quite simple and to the point:

 4. The result of the binary & operator is the bitwise AND of the operands (that is, each bit in the result is set if and only if each of the corresponding bits in the converted operands is set).

It's clear that the result cannot be 1, as the 1 bit is not set in the converted value of the right-hand-side operand (namely, 0x02).

Naturally, if undefined behavior has been invoked at some point in the program's past (or at compile time!), then anything can happen. Barring this possibility, however, your compiler is non-compliant. That is to say, broken. This, unfortunately, is extremely common on odd embedded compilers. If you're lucky, you may even be able to report the bug and get it fixed.

like image 6
bdonlan Avatar answered Oct 31 '22 12:10

bdonlan


I don't think the standard defines anything about this very specific and unusual issue. As said by aix, that statement can never be true because (in binary):

XXXX XXXX -> variable
0000 0010 -> 0x02
--------- AND
0000 00X0 -> result

(simplifying to 8-bit types)

So your only results can be 0000 0010 (which is 2) or 0000 0000 (which is 0).

like image 4
m0skit0 Avatar answered Oct 31 '22 12:10

m0skit0