Является ли этот троичный условным?: Правильный (объективный) синтаксис C? - PullRequest
36 голосов
/ 06 января 2012

Я не думал, что это было возможно, но, очевидно, в Задаче C это разрешено:

int a = b ?: c;

Итак, вы видите, что они здесь делают, они пропускают вторую часть троичного выражения, так что если b ненулевое, b используется как вторая часть.

Это умно, но, насколько я знаю, это против K & R C и, вероятно, ANSI C.

Если нет, то я упускал ужасно умный синтаксический прием в течение многих лет ... увы!

Обновление: Это gcc.

Ответы [ 4 ]

69 голосов
/ 06 января 2012

С http://en.wikipedia.org/wiki/%3F%3A

Расширение GNU для C позволяет опустить второй операнд и неявно использовать первый операнд в качестве второго:

a = x ? : y;

Выражениеэквивалентно

a = x ? x : y;

за исключением того, что если x является выражением, оно вычисляется только один раз.Разница значительна, если оценка выражения имеет побочные эффекты.

6 голосов
/ 19 января 2012

Это поведение определено как для gcc, так и для clang.Если вы создаете код для Mac OS X или iOS, нет причин не использовать его.

Я бы не стал использовать его в переносимом коде, без тщательного рассмотрения.

1 голос
/ 06 января 2012
$ cat > foo.c
#include <stdio.h>

int main(int argc, char **argv)
{
  int b = 2;
  int c = 4;
  int a = b ?: c;
  printf("a: %d\n", a);
  return 0;
}
$ gcc -pedantic -Wall foo.c
foo.c: In function ‘main’:
foo.c:7: warning: ISO C forbids omitting the middle term of a ?: expression

Так что нет, это не разрешено. Что в этом случае выдает gcc:

$ ./a.out 
a: 2

Итак, неопределенное поведение делает то, что вы говорите в своем вопросе, даже если вы не хотите на это полагаться.

1 голос
/ 06 января 2012

Это расширение GNU C . Проверьте настройки компилятора (ищите C-аромат). Не уверен, что это часть Clang, единственная информация, которую я могу получить, это на этой странице :

Введение

В этом документе описываются языковые расширения, предоставляемые Clang. В дополнение к языковым расширениям, перечисленным здесь, Clang стремится поддерживать широкий спектр расширений GCC. Пожалуйста, см. Руководство GCC для получения дополнительной информации об этих расширениях.

...