I can understand why the assignment operator is right associative. It makes sense that when
x = 4 + 3
is evaluated, that 4 and 3 are added before being assigned to x.
I am unclear as to how ?:
would benefit from being right associative. Does it only matter when two ?:
s were used like this
z = (a == b ? a : b ? c : d);
Then it is evaluated like this:
z = (a == b ? a : (b ? c : d));
Surely it would make more sense to evaluate from left to right?
Conditional expressions have right-to-left associativity. The first operand must be of integral or pointer type. The following rules apply to the second and third operands: If both operands are of the same type, the result is of that type.
The right-associativity of the = operator allows expressions such as a = b = c to be interpreted as a = (b = c) . In C++, the assignment a = b is an expression that evaluates to the same value as the expression a , with the side effect of storing the R-value of b into the L-value of a .
When operator + is said to be left-associative, this means that a + b + c is equivalent to (a + b) + c , as opposed to a + (b + c) . The operator = is right-associative, which means that a = b = c is equivalent to a = (b = c) , as opposed to (a = b) = c . Associativity has nothing to do with the order of evaluation.
If it evaluated from left to right, it'd look like this:
z = ((a == b ? a : b) ? c : d);
That is, it would use the result of the first conditional (a
or b
) as the boolean condition of the second conditional. That doesn't make much sense: that's like saying:
int z, tmp; /* first conditional */ if(a == b) tmp = a; else tmp = b; /* second conditional */ if(tmp) z = c; else z = d;
While perhaps one day you'll want to do exactly this, it's far more likely that each ?:
that follows is meant to add more conditions, like if
/ else if
/ else if
/ else
, which is what the right-associative binding yields:
int z; /* first conditional */ if(a == b) z = a; else /* second conditional */ if(b) z = c; else z = d;
In any language with a right associative ternary operator, you can stack them and build an if-elseif-elseif-else expression, like this:
val = a == 0 ? 1: a == 1 ? 2: 4;
On the contrary, in languages with a left associative ternary operator (such as PHP, thanks @user786653) you need to explicitly enforce the aforementioned intent with parentheses:
<?php // This will output 't', not 'true'. echo (true ? 'true' : false ? 't' : 'f'); // the following is a more obvious version of the same code as above echo ((true ? 'true' : false) ? 't' : 'f'); // here, you can see that the first expression is evaluated to 'true', which // in turn evaluates to (bool)true, thus returning the true branch of the // second ternary expression. ?>
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