Подтвердить что ты не робот

Условные разности операторов между C и С++

Я где-то читал, что оператор ?: в C немного отличается в С++, что есть некоторый исходный код, который по-разному работает на обоих языках. К сожалению, я не могу найти текст нигде. Кто-нибудь знает, в чем состоит эта разница?

4b9b3361

Ответ 1

Условный оператор в С++ может возвращать lvalue, тогда как C не позволяет использовать аналогичные функции. Следовательно, в С++ допустимо следующее:

(true ? a : b) = 1;

Чтобы воспроизвести это на C, вам придется прибегать к if/else или напрямую обращаться к ссылкам:

*(true ? &a : &b) = 1;

Также в С++ операторы ?: и = имеют равный приоритет и группу справа налево, так что:

(true ? a = 1 : b = 2);

является допустимым кодом С++, но будет вызывать ошибку в C без круглых скобок вокруг последнего выражения:

(true ? a = 1 : (b = 2));

Ответ 2

Основное практическое отличие состоит в том, что в C оценка?: никогда не может привести к l-значению, где, как и в С++, оно может.

Существуют и другие различия в его определении, которые имеют мало практических последствий. В С++ первый операнд преобразуется в bool, в C он сравнивается с 0. Это аналогично различию в определении ==,!= И т.д. Между C и С++.

В С++ существуют также более сложные правила для вывода типа выражения?: на основе типов 2-го и 3-го операндов. Это отражает возможность пользовательских неявных преобразований в С++.

Пример кода. Действительный С++; недействительный 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 assign" при компиляции как C, но код компилируется без ошибок при компиляции как С++.

Edit: Хотя?: Не может вернуть l-значение в C, возможно, удивительно, что грамматика для?: Is:

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

Это означает, что a ? b : c = d анализирует как (a ? b : c) = d, хотя (из-за правила 'не l-value') это не может привести к допустимому выражению.

С++ изменяет грамматику на следующее:

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

В то время как расширение, позволяющее условному выражению быть l-значением в некоторых ситуациях, сделало бы a ? b : c = d действительным без изменения грамматики, новое изменение грамматики означает, что выражение теперь действительное, но с другим значением a ? b : (c = d).

Хотя у меня нет никаких доказательств этого, мое предположение, что, поскольку изменение грамматики не могло нарушить совместимость с существующим C-кодом, более вероятно, что новая грамматика создаст меньше сюрпризов с такими выражениями, как:

make_zero ? z = 0 : z = 1;