Xorty
Xorty

Reputation: 18861

Why is this code resolved to true?

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

Answers (3)

John Marshall
John Marshall

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

CB Bailey
CB Bailey

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

David Grayson
David Grayson

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

Related Questions