简体   繁体   中英

Order of evaluation for conditional operator

It is known that both assignment = and conditional ?: operators have right associativity. In following code sample:

#include <stdio.h>

int main(void)
{
    int a, b, c, d;

    a = b = c = d = 1;
    1 ? a++ : b ? c++ : d;

    printf("%d %d %d %d\n", a, b, c, d);
    return 0;
}

the assignment:

a = b = c = d = 1;

is equivalent to:

a = (b = (c = (d = 1)));

and correspondingly:

1 ? a++ : b ? c++ : d;

is the same as:

1 ? a++ : (b ? c++ : d);

What the Standard say about this last case? Does it guarantee that such combined expression is evaluated from left to right (so the c++ part is not evaluated), just as opposite to assignment?

The evaluation order of ?: is guaranteed: the first operand is evaluated first, then evaluate the second or the third operand depending on whether the first operand is true.

You are mainly confused about the relationship between operator precedence/associativity and order of evaluation . They play different roles. The former decides how operators are grouped, while the latter decides which sub-expression is evaluated first.

Consider the expression a * b + c * d , the precedence rule means it's equivalent to (a * b) + (c * d) . But is it guaranteed that the compiler will evaluate a * b before c * d ? The answer is no, in this example, the operator + doesn't guarantee the order of evaluation.

The conditional operator ?: is one of the few operators that do have a specified order of evaluation. (The rest are && , || , and , ).


In your example

1 ? a++ : b ? c++ : d;
1 ? a++ : (b ? c++ : d);

are always equivalent, in both expressions, 1 is evaluated first, and since it's true, a++ is evaluated next, the end.

Associativity and precedence do not define order of evaluation . These concepts are completely unrelated. Order of evaluation in C is defined by sequencing rules, not by precedence or associativity.

It is true that a = b = c = d = 1; is associated as a = (b = (c = (d = 1))); , but that does not mean that d = 1 should be evaluated first, especially in C language, where assignment operator evaluates to an rvalue.

Associtivity simply says that c should receive value 1 converted to the type of d ("as if" it was read from d ). But that does not mean that d = 1 should be done first. In your example all variables have the same type, which means that the whole thing is equivalent to a = 1; b = 1; c = 1; d = 1; a = 1; b = 1; c = 1; d = 1; in absolutely any order. There's no sequencing inside a = b = c = d = 1 expression.

The same logic applies to ?: operator. Its associativity simply tells you which operand belongs to which operator. And the grouping is indeed 1 ? a++ : (b ? c++ : d); 1 ? a++ : (b ? c++ : d); . But associativity does not tell you anything about the order of evaluation. Order of evaluation in ?: operator is defined separately and independently: the condition is always evaluated (sequenced) first, then one (and only one) of the branches is evaluated. In your example 1 is evaluated first, then a++ is evaluated and its result becomes the result of the entire expression. The (b ? c++ : d) part is not even touched.

1 ? a++ : b ? c++ : d;

is equivalent to

if (1) {
    a++;
}
else {
    if (b) {
        c++;
    }
    else {
        d;
    }
}

So, the output will be

2 1 1 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM