Reputation: 18861
int main() {
int a = 1;
int b = 0;
if (a = b || ++a == 2)
printf("T: a=%i, b=%i", a, b);
else
printf("F: a=%i, b=%i", a, b);
return 0;
}
Let's take a look at this simple code snippet. Result is: T: a=1, b=0
Why? (note a=b
uses assignment operand, not comparison)
What I understand here, is that zero is assigned to a, then a is incremented to 1. 1 is not equal to 2. So result should indeed be a=1, b=0. But why is this condition evaluated to true? Neither of (a=b)
or (++a == 2)
is true ... What did I miss?
Here is other short program that prints F as expected:
int main() {
int a = 1;
int b = 0;
if (a = b) printf("T"); else printf("F");
return 0;
}
Upvotes: 13
Views: 380
Reputation: 7005
If you are using GCC or another compiler with similarly useful warnings, turning warnings on would give you a very large hint as to what's gone wrong here. With gcc -Wall
:
warning: suggest parentheses around assignment used as truth value
To be precise: the compiler is interpreting the code as if (a = (b || ++a == 2))
, and the warning is suggesting that you write it as if ((a = (b || ++a == 2)))
to emphasize that the code is as intended, not a typo for the more common if (a == (b || ++a == 2))
.
So the warning requires a bit of interpretation. To get your desired effect, coincidentally enough you need to add parentheses around a different assignment used as a truth value, namely (a = b)
. Nonetheless the warning tells you that something is untoward about this particular line of code and that it deserves further scrutiny.
Upvotes: 0
Reputation: 791949
You have confused yourself with misleading spacing.
if (a = b || ++a == 2)
is the same as:
if (a = (b || ((++a) == 2)))
This actually has undefined behavior. Although there is a sequence point between the evaluation of b
and the evaluation of ((++a) == 2)
, there is no sequence point between the implied assignment to a
and the other write to a
due to the explicit =
assignment.
Upvotes: 27
Reputation: 87416
Actually, assignment has the lowest operator precedence so your if statement is equivalent to:
if ( a = ( b || ( ++a == 2 ) ) )
So you're assigning a to 1 but also incrementing it in the same expression. I think that leads to undefined behavior, but the end result is that a is 1 in your compiler.
Upvotes: 2