Почти все таблицы приоритетов операторов C/C++, с которыми я консультировался, указывают, что тернарный условный оператор имеет более высокий приоритет, чем операторы присваивания. Однако есть несколько таблиц, например, в википедии и в operator-precedence.com, что ставит их на один уровень приоритета. Какой он, выше или такой же?
Действительно ли тернарный оператор C/C++ имеет тот же приоритет, что и операторы присваивания?
Ответы (3)
В грамматике C++
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
можно было бы объединить в
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
Если смотреть только на =
и ?:
и игнорировать внутреннее выражение между ?
и :
, это явно дает ?:
и =
точно такой же приоритет.
Это отличается от грамматики C, в которой ни левый, ни правый операнд ?:
не могут иметь оператора присваивания в качестве самого верхнего оператора.
assignment-expression: conditional-expression unary-expression assignment-operator assignment-expression conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression
Так что для C имеет смысл дать им разные уровни приоритета.
Тем не менее, уровни приоритета являются лишь приближением к тому, что на самом деле говорит стандарт, будут случаи для любых выбранных вами уровней приоритета, которые покажут, что уровни вводят в заблуждение или просто неверны. В зависимости от вашей интерпретации внутреннее выражение ?:
может быть одним из них, это для меня.
a = b ? c : d
b ? c : d
является подвыражением содержащего выражения присваивания, но ни одно из них не указано в скобках.
- person ; 22.11.2012
a = b
b
является выражением инициализатора, независимым от =
(после того, как приоритет был установлен)
- person Maxim Egorushkin; 22.11.2012
int a = b;
. a = b;
— обычное выражение-присваивания, инициализации нет.
- person ; 22.11.2012
a = b ? c : d
будет эквивалентно (a = b) ? c : d
.
- person avakar; 22.11.2012
a ? b : c = d
, но я избегал этого в своем ответе :)
- person ; 22.11.2012
a ? b = c : d
, поэтому второй пример бесполезен. Первый пример просто показывает, что ?
имеет более высокий (или такой же) приоритет, чем =
.
- person anatolyg; 22.11.2012
Ответ для C++ заключается в том, что ?:
и =
имеют одинаковый приоритет. Да, почти каждая таблица приоритетов операций C++ неверна.
В C не имеет значения, выше ли ?:
, чем =
, потому что в C оператору ?:
не разрешено вычислять l-значение, что он должен был бы делать, если бы приоритет влиял на поведение (с учетом что они уже являются RTL-ассоциативными). См., например, обсуждение под ответом Лучиана Кригора.
Возможно, эта ошибка настолько распространена, потому что ранние таблицы приоритетов операций C++ могли быть скопированы и расширены из таблиц C. И, возможно, ошибка сохранилась потому, что единственный контрпример — выражения вида a?b:c=d
— используются редко. Возможно.
Вы найдете это в стандарте:
5 выражений [выражение]
58) Приоритет операторов прямо не указан, но его можно вывести из синтаксиса. (Примечание)
Это означает, что таблицы приоритетов выводятся, а не указываются. Пока они ведут себя одинаково, можно сказать, что оба правы. Таким образом, даже если таблица приоритетов помещает их как имеющие одинаковый приоритет или помещает тройку выше оператора присваивания, на практике происходит то же самое из-за синтаксиса.
Обратите внимание, что здесь большую роль играет ассоциативность (это также вытекает из синтаксиса).
Даже если вы предполагаете, что они имеют одинаковый приоритет:
a = b ? c : d;
будет рассматриваться как a = (b ? c : d)
, потому что они оба являются ассоциативными справа налево.
a?b:c=d
. Это (a?b:c)=d
или это a?b:(c=d)
?
- person Museful; 22.11.2012
a?b:(c=d)
. Я уже говорил, что в данном случае важнее ассоциативность.
- person Luchian Grigore; 22.11.2012
(a?b:c)=d
.
- person Museful; 22.11.2012