Does the C/C++ ternary operator actually have the same precedence as assignment operators?

南楼画角 提交于 2019-11-28 12:15:01

In the C++ grammar,

assignment-expression:
    conditional-expression
    logical-or-expression assignment-operator initializer-clause
    throw-expression

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

initializer-clause:
    assignment-expression
    braced-init-list

could be combined to

assignment-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression
    logical-or-expression assignment-operator assignment-expression
    logical-or-expression assignment-operator initializer-clause
    throw-expression

If only looking at = and ?:, and if ignoring the inner expression between ? and :, this clearly gives ?: and = the exact same precedence.

This is different from the C grammar, in which neither ?:'s left nor its right operand can have an assignment operator as its topmost operator.

assignment-expression:
    conditional-expression
    unary-expression assignment-operator assignment-expression

conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

So for C, it makes sense to give them different precedence levels.

That said, precedence levels are only an approximation of what the standard actually says, there will be cases for any precedence levels you choose that show the levels to be misleading or just plain wrong. Depending on your interpretation, the inner expression of ?: may be one of them, it is for me.

The answer for C++ is that ?: and = have the same precedence. Yes, almost every C++ operator precedence table out there is wrong.

In C it doesn't matter whether ?: is higher than = or not, because in C the ?: operator is not allowed to evaluate to an l-value, which is what it would have to do if precedence were to influence the behavior (given that they are already RTL associative). See the discussion under Luchian Crigore's answer for example.

Perhaps this error is so widespread because early C++ operator precedence tables may have been copied and extended from C tables. And perhaps the error has persisted because the only counterexample - expressions of the form a?b:c=d - are rarely used. Perhaps.

Luchian Grigore

You'll find that, in the standard:

5 Expressions [expr]

58) The precedence of operators is not directly specified, but it can be derived from the syntax. (note)

This means precedence tables are inferred, not specified. As long as they behave the same, you can say that both are right. So, even if a precedence table places them as having the same precedence, or places the ternary above the assignment operator, in practice the same thing happens, because of the syntax.

Note that associativity plays a bigger role here (this is also derived from the syntax).

Even if you assume that they have the same precedence:

a = b ? c : d;

will be treated as a = (b ? c : d) because they are both right-to-left associative.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!