Reputation: 53
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.
Upvotes: 5
Views: 1758
Reputation: 500407
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.
Upvotes: 11
Reputation: 15954
For C, the answer is no.
The C standard says about &
(6.5.10):
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).
Since in 2
only the bit 1 is set, the value of the expression can only have set the bit 1. It can take no other values than 2 and 0. Neither 2 nor 0 can compare equal to 1.
The bit representations of integers are defined in 6.2.6.2 (for non-negative values in the usual way).
Upvotes: 1
Reputation: 9393
Let us consider the binary value of 2
02 = 0010 (say a 4 bit number)
and the binary value of 1 is
01 = 0001
The least significat bit of 2 is always zero that is the left most bit is 0. SO
The & (and) operation with 0 never gives 1 hence we can say it can never be equal to 1
0 0 => 0
0 1 => 0
1 1 => 1
Note: & indicates the bit wise and operation
2 - 0010
3 - 0011
0010
So the output with xx & 2 will be 0 or 2.
Upvotes: 0
Reputation: 231193
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.
Upvotes: 6
Reputation: 31053
Basically, lint is right here. At least on any platform I know of, the condition will yield false. Look at the bit representation of the numbers: x & 2 (0010) will always be either zero or 2 (0010) and thus different from 1 (0001) for any integer x.
Upvotes: 0
Reputation: 25873
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).
Upvotes: 4