GCC has an awesome ternary expression extension to C which allows us to create a statement like this:
int x = some_var ?: 10; // expands to some_var ? some_var : 10
Which is really nice, and while it's not particularly intuitive, it does work. Most binary operators in the C language have an additional operator associated with them, which allows for assignment:
x = x + 2;
// instead, we can say
x += 2;
Since this is the case, and the norm for most binary C operators (+
, -
, *
, /
, %
, |
, &
, ^
), why isn't this the case for the ternary extension operator:
int x = ...;
x ?:= 2; // error: Expected expression before '=' token
// which would expand to
x = x ?: 2;
The only operators which don't support this in standard C are the logical operators (||
, &&
), which the definitely ternary doesn't fall under, so why can't we do this?
I would really like to make a smiley face with a cool hair-do in my code, but I can't! Was this an oversight in designing the operator, or intentional and documented somewhere? Is it a result of the operator short-circuiting its operand, or something else entirely?
To answer the question, I believe there are some other questions that needs to be answered as well.
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
and then they illustrate this with the line
which is their own subjective, muddy opinion. Personally, I believe that
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:
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:
The answer to this is mentioned here:
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:
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 avolatile
- reading a volatile variable is a side effect. So the only practical use I can see withx ?:= 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.