Необычное использование условного оператора в Linux
В ядре Linux 3.0.4, mm/filemap.c имеет следующую строку кода:
retval = retval ?: desc.error;
Я пробовал скомпилировать подобный минимальный тестовый пример с gcc -Wall и не получать никаких предупреждений; поведение похоже на:
retval = retval ? retval : desc.error;
Глядя на стандарт C99, я не могу понять, что формально описывает это поведение. Почему это нормально?
Ответы
Ответ 1
Как уже говорили некоторые другие, это расширение GCC, не являющееся частью какого-либо стандарта. Вы получите предупреждение об этом, если используете переключатель -pedantic
.
Точка этого расширения на самом деле не видна в этом случае, но представьте, если бы это было
retval = foo() ?: desc.error;
С расширением foo()
вызывается только один раз. Без этого вы должны ввести временную переменную, чтобы дважды не называть foo()
.
Ответ 2
Это расширение gcc. x ?: y
эквивалентен x ? x : y
- см. http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals.
Да, я думаю, это тоже зло.
Ответ 3
Это расширение GCC, называемое Условные обозначения с опущенными операндами. Опускание среднего операнда влияет на использование значения условного числа как пропущенного операнда, не оценивая его снова. Это безопасно использовать, даже если условный макрос.
Ответ 4
Это gcc-специфическое расширение для C и не является стандартным.