0

I have the solution regarding execution order, but I cant understand how right associativity is linked to SCENARIO 2.

a ? b: c ? d : e ? f : g ? h : i // scenario 1 : associativity understood, which is : (a?b:(c?d:(e?f:(g?h:i))))

and

a ? b ? c : d : e // scenario 2 : NOT UNDERSTOOD

From the first answer here, I am able to understand the first scenario but not the second.

  • 2
    Nobody writes conditional statements this way unless they are participating in a code obfuscation competition. What's the goal here? See the [documentation](https://en.cppreference.com/w/cpp/language/operator_precedence#cite_note-2). – paddy Sep 05 '22 at 02:03
  • Yes @paddy, it was a question to quizz the skills of learner. I understand scenario 1 , but not 2 – Raman Kumar Sep 05 '22 at 02:04
  • Well it's unclear what problem you're actually having. It's `a ? (b ? c : d) : e`. The statement is read from left to right. Imagine you're a compiler. The operators are the same precedence and so after `a ?` you hit `b ?` which nests until `c : d` resolves for the `b` conditional and then `: e` resolves for the `a` conditional. – paddy Sep 05 '22 at 02:14
  • But @paddy, why the statement is read from left, if the associativity of ternary is right to left? – Raman Kumar Sep 05 '22 at 02:16
  • That question is answered explicitly in the answer to the question you linked to. – paddy Sep 05 '22 at 02:17
  • 1
    I want to stress that even when you understand precedence completely, you should _never_ expect someone to read such a conditional in actual code. Always help them out with parentheses. This reduces cognitive load and makes the statement clearer. In general, you can avoid nesting conditionals and it usually results in code that is easier to read, easier to maintain, and contains fewer bugs. – paddy Sep 05 '22 at 02:18
  • @Paddy, thanks for ur advice. In the documentation u have linked, it is written, """ In C, the ternary conditional operator has higher precedence than assignment operators. Therefore, the expression e = a < d ? a++ : a = d, which is parsed in C++ as e = ((a < d) ? (a++) : (a = d)), will fail to compile in C due to grammatical or semantic constraints in C. """ I see that C++ also follows the same precedence, so will the code also not compile in C++ ? – Raman Kumar Sep 05 '22 at 02:23
  • @Raman - We don't care if it compiles in C++, because nobody would ever seriously write code like that. That is the solution to "Doctor, doctor, it hurts when I do this!". – BoP Sep 05 '22 at 07:49

1 Answers1

2

The obvious (and generally best) advice about things like this is "just don't do it."

Other than that, I find the easiest approach to be to think of them like Algol-style ifs. An Algol if was an expression, not a statement, so (much like a conditional, except readable) you could write something like this:

a = if b then c else d;

The transformation is really pretty simple. x ? is if (x) and : is else. Applying this to a nested conditional is actually pretty easy, and at least in my opinion, the result is much more readable.

a ? b: c ? d : e ? f : g ? h : i

Transforms to:

if (a) {
    b; 
} else if (c) {
    d; 
} else if (e) {
    f;
} else if (g) {
    h;
} else {
    i;
}

The second is actually just about as easy, as long as you remember that x ? translates directly to if (x). Other than that, we follow the normal C rule that an else matches up with the most recent if that doesn't already have an else associated with it.

a ? b ? c : d : e

...becomes:

if (a) {
    if (b) {
        c;
    }
    else {
        d;
    }
} else {
    e;
};
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • thank u :) with this explanation, i am able to completely understand the execution order without caring about associativity. can u pls also make me understand the associativity (why ternary is said right to left associative) – Raman Kumar Sep 05 '22 at 02:36
  • @RamanKumar: The standard doesn't use the word `associativity` to describe it. But to the extent that's meaningful, I assume it's referring to what's covered in the second example--that in `a ? b ? c : d : e`, the `b ?` associates with the `c` and `d`. But at least in my opinion, trying to think in terms of associativity tends lead to more problems that solutions. – Jerry Coffin Sep 05 '22 at 02:42
  • @RamanKumar Please drop the habit of referring to this operator as "ternary" or "the ternary operator". Sure, it is ternary in its function, but its name is the _conditional operator_. – paddy Sep 05 '22 at 02:44
  • @JerryCoffin, I just thought maybe we shouldnt use the term associativity here because, associativity will come into picture if there are two(or more) operators of the same precedence but here, two(or more) operators are actually NESTED, which rules out the concept of associativity. – Raman Kumar Sep 05 '22 at 03:01
  • @raman: in the syntax for the conditional operator, `?` and `:` function like grouping parentheses. Whatever is between them is grouped; precedence and associativity cannot be applied. So `a ? b ? c : d : e` is parsed identically to `a ? (b ? (c) : d) : e`. Associativity is irrelevant. Right associativity is what makes `a ? b : c ? d : e` parse as `a ? b : (c ? d : e)` (the natural interpretation), rather than the left associative `(a ? b : c) ? d : e`, which only makes sense to whoever wrote PHP. Similarly, `a = b = c` is `a = (b = c)`, unlike `a - b - c`, which is `(a - b) - c`. – rici Sep 05 '22 at 05:56
  • None of that has to do with execution order. The first argument (the condition) is evaluated first. Only one of the other two is evaluated. Obviously that evaluation cannot happen until you know which one to evaluate. Precedence and associativity determine what the arguments are, but have nothing to do with the order of evaluation. – rici Sep 05 '22 at 06:00