Reputation: 1146
While porting some C code to Windows, I've discovered an interesting ternary operator behavior in MSVC++. It appears that compiler evaluates both branches around ? :
in the following example:
#include <stdio.h>
struct S {
int x;
};
int getNum() {
printf("get num\n");
return 4;
}
int main(int argc, char **argv) {
struct S s = argc ? (struct S) { .x = getNum() } : (struct S) { .x = getNum() };
printf("%d\n", s.x);
return 0;
}
Prints:
get num
get num
4
But, GCC and Clang evaluate getNum()
only once. Which behavior is correct or allowed by the standard?
Upvotes: 7
Views: 1847
Reputation: 29985
According to C++11 §5.16.1 Conditional operator:
Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
According to C11 §6.5.15 Conditional operator:
The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.
Upvotes: 8