В открытом исходном коде Android qemu кодируют, я натыкался на эту строку кода:
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
Это просто запутывающий способ сказать:
if (machine->max_cpus) {
; //do nothing
} else {
machine->max_cpus = 1;
}
Если так, не был бы это быть более ясным как:
if (machine->max_cpus == 0) machine->max_cpus = 1;
Интересно, это компилирует и хорошо работает с gcc, но не компилирует на http://www.comeaucomputing.com/tryitout/.
Это разрешено в GNU как неясное расширение C
5.7 Условные выражения с опущенными операндами
Средний операнд в условном выражении может быть опущен. Тогда, если первый операнд отличен от нуля, его значение будет значением условного выражения .
Следовательно, выражение
x? : y
имеет значение x, если оно не равно нулю; в противном случае - значение y.
Этот пример полностью эквивалентен
x? x: y
В этом простом случае возможность опустить средний операнд не особенно полезна. Когда он становится полезным, это когда первый операнд, или может (если это аргумент макроса), содержать побочный эффект. Тогда повторение операнда в середине вызовет побочный эффект дважды. Если опустить средний операнд, используется значение , уже вычисленное без нежелательные эффекты его пересчета.
Как вы, наверное, догадались, этого рекомендуется избегать по причинам удобочитаемости и переносимости. Я искренне удивлен, увидев такое несовместимое с грамматикой расширение для C.
БНФ K&R показывает, что между "?" и ":" требуется выражение. Я не думаю, что gcc должен компилировать это без диагностики.
Это расширение GCC , которое означает «если условие истинно, используйте его, иначе используйте это другое значение», поэтому
machine->max_cpus = machine->max_cpus ?: 1;
является сокращением для
machine->max_cpus = machine->max_cpus ? machine->max_cpus : 1;
, хотя если у условного есть побочные эффекты, оно будет запущено только один раз
Это расширение GCC , и оно становится более интересным и полезным, когда условие имеет побочные эффекты .
В этом случае, да, я согласен, что это неясно больше всего на свете.
Используя флаг gcc -pedantic, он говорит
foo.c: 5: warning: ISO C запрещает опускать средний термин из?: выражение