To answer the question, I believe there are some other questions that needs to be answered as well.
Why is there a ?:
operator in the C language and why is it better
than if-else
?
As far as I know, nobody has been able to answer that question, without merely stating their own subjective opinions. K&R 2.11 states that
"The conditional expression often leads to succinct code."
and then they illustrate this with the line
printf("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');
which is their own subjective, muddy opinion. Personally, I believe that
printf("%6d", a[i]);
if(i%10==9 || i==n-1)
printf("\n");
else
printf(" ");
is far, far clearer since I can read and understand that code in 10 seconds, as opposed to 1 minute to read and understand the K&R version. Also, my code separates the integer printing from the unrelated formatting. But of course, that is my subjective opinion, there is no obvious right or wrong.
As for official sources, the C99 rationale version 5.10, 6.5.15 doesn't really mention why the ?: operator is needed either. It mainly just states that the behavior of the operator has been altered in the new standard:
The syntactic restrictions on the middle operand of the conditional
operator have been relaxed to include more than just
logical-OR-expression: several extant implementations have adopted
this practice.
The type of a conditional operator expression can be void, a
structure, or a union; most other operators do not deal with such
types. The rules for balancing type between pointer and integer have,
however, been tightened, since now only the constant 0 can portably be
coerced to a pointer.
So if someone has an urge to perform arithmetic on struct or union types, the ?: is supposedly more handy than if-else. I see no obvious benefit from this, but at least it is some reason for the operator to exist.
The next question would then be:
Why is there a compiler extension to the ?:
operand in the GCC
compiler?
The answer to this is mentioned here:
When it becomes useful is when the first operand does, or may (if it
is a macro argument), contain a side effect. Then repeating the
operand in the middle would perform the side effect twice. Omitting
the middle operand uses the value already computed without the
undesirable effects of recomputing it.
So this GCC extension has nothing to do with readability or language consistency, it was merely added to avoid unwanted side effects.
Then to attempt to answer the original question:
Why doesn't GCC's ternary extension support assignment?
Probably because accessing the lvalue in an assignment condition doesn't typically yield any unwanted side effects. x = x ? : 2;
would only have unwanted side effects if x was declared as a volatile
- reading a volatile variable is a side effect. So the only practical use I can see with x ?:= 2;
would be to prevent someone from accessing the same volatile variable twice in the same conditional expression.
And that is a feature of very narrow and limited value. It would perhaps be useful in some special embedded system case where you read hardware registers in a demanding real-time system... apart from that, I see no uses for it.
Nor can I find any official or canonical sources stating any use for the ?: operator itself, apart from tradition and subjective coding style preferences.
x ?:= 2;
would mean, but maybex ?= ValueWhenXTrue:ValueWhenXFalse;
. – Espadrilleif x is zero, set it to 2
. – Puffx ?:= 2
be? In the expression:a = x ? b : c
, there are four operands, in the extensiona = x ?: b
there are three, in your proposala ?:= b
there are only two - the value being assigned and the value to be assigned, but no conditional - you have rendered it meaningless - there is no reasonable semantic interpretation. – Lavaint x = some_var ?: 10;
is awesome, or would solve any programming problem, or make the code less confusing. – Vasya?:=
not existing. Let's join WG14 and suggest a change to the Standard (maybe it gets into the next Standard). – Ynez