Consider the following piece of code:
int i, k, m;
k = 12;
m = 34;
for (i = 0; i < 2; i++) ((i & 1) ? k : m) = 99 - i;
printf("k: %ld m: %ld\n\n", k, m);
In this silly example, the conditional operator expression is a shortcut for:
if (i & 1) k = 99 - i; else m = 99 - i;
My compiler does not complain and executing this piece of code gives the expected output
k: 98 m: 99
My question, though, is if this is valid code according to the C standard? I have never seen anything like it used before.
The conditional operator (? :) is a ternary operator (it takes three operands). The conditional operator works as follows: The first operand is implicitly converted to bool . It is evaluated and all side effects are completed before continuing.
The conditional operator in the C programming language The conditional operator can help you make decision-making statements in just a single line, where an if-else would take more than one line. The conditional operator takes three operands, so it is a ternary operator.
Conditional OR The operator is applied between two Boolean expressions. It is denoted by the two OR operator (||). It returns true if any of the expression is true, else returns false.
Footnote 110 in the C11 standard:
A conditional expression does not yield an lvalue.
And 6.5.16 paragraph 2:
An assignment operator shall have a modifiable lvalue as its left operand.
So no, that code does not conform to the C standard.
In C++11, it is valid:
If the second and third operands are lvalues and have the same type, the result is of that type and is an lvalue.
So this is another one of those dusty corners where C and C++ differ significantly. If your compiler doesn't produce an error, then I'm guessing you're using a C++ compiler with a "C mode", rather than a proper C compiler; MSVC?
This is not legal C, and a compiler that accepts it is wrong. However, you can do the same thing with:
*((i & 1) ? &k : &m) = 99 - i;
and it becomes legal C.
It is valid to use conditional as an lval in C++, but not in C.
In C++ (ISO?IEC 14882:1998(E) 5.16.4)
If the second and third operands are lvalues and have the same type, the result is of that type and is an lvalue.
If you would like to use similar trick in C, you should use pointers:
ISO/IEC 9899:TC2, 6.5.14.6
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types pointed-to by both operands.
*((i & 1) ? &k : &m) = 99 - i;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With