Странное использование условного оператора в Linux - PullRequest
37 голосов
/ 19 октября 2011

В ядре Linux 3.0.4, mm / filemap.c имеет следующую строку кода:

retval = retval ?: desc.error;

Я попытался скомпилировать аналогичный минимальный тестовый пример с помощью gcc -Wall и не получил никаких предупреждений; поведение кажется идентичным:

retval = retval ? retval : desc.error;

Глядя на стандарт C99, я не могу понять, что формально описывает это поведение. Почему это нормально?

Ответы [ 4 ]

36 голосов
/ 19 октября 2011

Как уже говорили несколько других, это расширение GCC, а не часть какого-либо стандарта. Вы получите предупреждение об этом, если будете использовать переключатель -pedantic.

Точка этого расширения на самом деле не видна в этом случае, но представьте, что вместо этого

retval = foo() ?: desc.error;

С расширением foo() вызывается только один раз. Без этого вам придется ввести временную переменную, чтобы избежать двойного вызова foo().

19 голосов
/ 19 октября 2011

Это расширение gcc.x ?: y эквивалентно x ? x : y --- см. http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals.

Да, я думаю, это тоже зло.

7 голосов
/ 19 октября 2011

Это расширение GCC, которое называется Условные выражения с пропущенными операндами .Пропуск среднего операнда приводит к использованию значения условного операнда в качестве пропущенного операнда без его повторной оценки.Безопасно использовать, даже если условным является макрос.

3 голосов
/ 19 октября 2011

Это специфичное для gcc расширение C и не стандартное.

...