В C, когда поддерживается условная форма "test?: Alt" (пустой истинный случай)?

В gcc я могу написать foo ? : bar, который является сокращенной формой foo ? foo : bar, но я вижу, что K & R не упоминает об этом.

Я полагаюсь на это, о чем я должен полагаться, определенный в каком-то стандарте? Или просто (зло) gcc-расширение, которого я должен избегать?

Ответы

Ответ 1

Это расширение GCC по имени:
Условные обозначения с опущенными операндами.

Это не стандарт c.Using -pedantic флаг для компиляции скажет вам об этом.

Средний операнд условного выражения может быть опущен. Тогда, если первый операнд отличен от нуля, его значение является значением условного выражения.

Следовательно, выражение

    x ? : y

имеет значение x, если оно отличное от нуля; в противном случае значение y.

Этот пример абсолютно эквивалентен

    x ? x : y

В этом простом случае способность опускать средний операнд не особенно полезна. Когда это становится полезным, это когда первый операнд делает или может (если он является аргументом макроса), содержит побочный эффект. Затем повторение операнда в середине будет выполнять побочный эффект дважды. Опускание среднего операнда использует значение, уже вычисленное без нежелательных эффектов пересчета.

Я полагаюсь на это, о чем я должен полагаться, определенный в каком-то стандарте? Или просто (зло) gcc-расширение, которого я должен избегать?

В зависимости от ваших требований, если ваш код не должен запускаться ни в какой другой реализации компилятора, кроме GCC, вы можете его использовать. Однако, если ваш код должен строиться на разных реализациях компилятора, вы не должны его использовать.

Во всяком случае, нужно стремиться максимально писать интуитивно понятный и понятный код, учитывая, что я всегда предлагаю избегать таких (уродливых) конструкций.

Ответ 2

Это расширение GCC. Он не является частью стандарта C, но компилятор GCC позволяет использовать его. Подробнее см. В документации и помните о его поведенческих отличиях к "эквивалентному" тернарному выражению.

Ответ 3

Это расширение, включенное в GCC.

Он не будет работать при компиляции с другим компилятором (который не поддерживает это расширение).

Поэтому я бы рекомендовал не использовать этот тип ярлыка.

EDIT: Как отметил @KevinCox, даже < <20 > не будет работать (см. второй комментарий ниже).