0
std::cout << (true ? "high pass" : false ? "fail" : "pass")

is the same as

std::cout << (true ? "high pass" : (false ? "fail" : "pass"))

Since the ternary operator is right associative, why don't we perform the right-hand operation first? Shouldn't pass be printed instead of high pass?

phuclv
  • 37,963
  • 15
  • 156
  • 475
JayYay
  • 27
  • 3
  • 3
    Associativity has nothing to do with order of evaluation. Associativity governs (roughly speaking) how implicit parentheses are placed, but nothing more. – HolyBlackCat Jan 08 '21 at 10:31
  • @HolyBlackCat And doesn't parenthesis dictate what operation is performed first? – JayYay Jan 08 '21 at 10:35
  • 3
    They don't. [Those rules](https://en.cppreference.com/w/cpp/language/eval_order) dictate the order of evaluation. Of course parentheses set some limits on the order of evaluation, e.g. in `(1+2)*(3-(4/2))` the `*` must be evaluated last. But `/` doesn't have to be evaluated before `+`. – HolyBlackCat Jan 08 '21 at 10:37

2 Answers2

4

You misunderstood operator associativity. It's simply the way to group operators with the same precedence and doesn't affect order of evaluation in any way. So cond1 ? 1 : cond2 ? 2 : cond3 ? 3 : 4 will be parsed as

cond1 ? 1 : (cond2 ? 2 : (cond3 ? 3 : 4))

from the right and not as

((cond1 ? 1 : cond2) ? 2 : cond3) ? 3 : 4

which groups operands from the left. Once parentheses are "added" then the expression will be evaluated in its normal order

In fact PHP made the ternary operator left-associative which is one of its biggest mistake and it's unfixable by now. See Understanding nested PHP ternary operator
Update: The left-associativity of the ternary operator has been deprecated in PHP 7.4 and removed in PHP 8.0

phuclv
  • 37,963
  • 15
  • 156
  • 475
0

The Ternary Operator works like

variable = (condition) ? expressionTrue : expressionFalse;

This could be expressed like

if (condition)
{
  expressionTrue;
}
else
{
  expressionFalse;
} 

The condition of both of your statements statements is true, so the expressionTrue will be always executed. There is no reason to check the expressionFalse in a statement like

std::cout << (true ? "high pass" : (false ? "fail" : "pass"))
Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
  • But doesn't associativity dictate what operation is performed first (hence the parenthesis around the right-most ternary operator)? Also, there's a mistake in your answer; one statement is false. – JayYay Jan 08 '21 at 10:34
  • 3
    @JayYay *"associativity dictate what operation is performed first"* It doesn't. Associativity tells the compiler that `true ? "high pass" : false ? "fail" : "pass"` means `true ? "high pass" : (false ? "fail" : "pass")` rather than `(true ? "high pass" : false) ? "fail" : "pass"`, and nothing more. – HolyBlackCat Jan 08 '21 at 10:35
  • @HolyBlackCat Can you elaborate on what associativity means then? Excuse my ignorance (I'm a beginner). – JayYay Jan 08 '21 at 10:38
  • 2
    @JayYay I'm not sure how to explain it (more than I already did). Another example: `a/b/c` means `(a/b)/c` rather than `a/(b/c)`, because `/` is left-to-right associative. – HolyBlackCat Jan 08 '21 at 10:42