Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Valid use of the conditional operator?

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.

like image 651
zarulad Avatar asked Apr 05 '12 15:04

zarulad


People also ask

What is the use of conditional operator?

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.

What is the use of conditional operator in C?

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.

What is the use of conditional operator in Java?

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.


3 Answers

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?

like image 73
Stephen Canon Avatar answered Sep 22 '22 09:09

Stephen Canon


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.

like image 20
R.. GitHub STOP HELPING ICE Avatar answered Sep 19 '22 09:09

R.. GitHub STOP HELPING ICE


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;
like image 30
Sergey Kalinichenko Avatar answered Sep 18 '22 09:09

Sergey Kalinichenko