Я где-то читал, что оператор ?:
в C немного отличается от оператора в C++, что есть какой-то исходный код, который работает по-разному в обоих языках. К сожалению, я нигде не могу найти этот текст. Кто-нибудь знает, в чем заключается эта разница?
Условный оператор в C++ может возвращать l-значение, в то время как C не допускает подобной функциональности. Следовательно, в C++ законно следующее:
(true ? a : b) = 1;
Чтобы повторить это в C, вам придется прибегнуть к if/else или работать со ссылками напрямую:
*(true ? &a : &b) = 1;
Также в C++ операторы ?:
и =
имеют одинаковый приоритет и группируются справа налево, так что:
(true ? a = 1 : b = 2);
является корректным кодом на C++, но без круглых скобок вокруг последнего выражения вызовет ошибку на C:
(true ? a = 1 : (b = 2));
Основное практическое различие заключается в том, что в C оценка ?: никогда не может привести к l-значению, а в C++ может.
Есть и другие различия в его определении, которые имеют мало практических последствий. В C++ первый операнд преобразуется в bool, в C он сравнивается с 0. Это аналогично разнице в определении ==, != и т.д. между C и C++.
В C++ также существуют более сложные правила для вывода типа выражения ?: на основе типов второго и третьего операндов. Это отражает возможность определяемых пользователем неявных преобразований в C++.
Пример кода. Действительный C++; недействительный C.
extern int h(int p, int q);
int g(int x)
{
int a = 3, b = 5;
(x ? a : b) = 7;
return h( a, b );
}
gcc
выдает ошибку: "error: invalid lvalue in assignment" при компиляции как C, но код компилируется без ошибок при компиляции как C++.
Edit: Хотя ?: не может вернуть l-значение в Си, возможно, удивительно, что грамматика для ?: такова:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
Это означает, что a ? b : c = d
разбирается как (a ? b : c) = d
, хотя (из-за правила 'не l-значения') это не может привести к корректному выражению.
C++ изменяет грамматику следующим образом:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
Хотя расширение, позволяющее условному выражению быть l-значением в некоторых ситуациях, сделало бы a ? b : c = d
допустимым без изменения грамматики, новое изменение грамматики означает, что выражение теперь допустимо, но с другим значением a ? b : (c = d)
.
Хотя у меня нет никаких доказательств этого, мое предположение, что поскольку изменение грамматики не могло нарушить совместимость с существующим кодом на языке Си, более вероятно, что новая грамматика будет создавать меньше сюрпризов с такими выражениями, как:
make_zero ? z = 0 : z = 1;