Почему Вы использовали бы тернарный оператор, не присваивая значение для “истинного” условия (x = x?: 1)

В открытом исходном коде 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/.

39
задан VividD 8 January 2014 в 13:13
поделиться

5 ответов

Это разрешено в GNU как неясное расширение C

5.7 Условные выражения с опущенными операндами

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

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

  x? : y 
 

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

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

  x? x: y 
 

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

Как вы, наверное, догадались, этого рекомендуется избегать по причинам удобочитаемости и переносимости. Я искренне удивлен, увидев такое несовместимое с грамматикой расширение для C.

50
ответ дан 27 November 2019 в 02:36
поделиться

БНФ K&R показывает, что между "?" и ":" требуется выражение. Я не думаю, что gcc должен компилировать это без диагностики.

1
ответ дан 27 November 2019 в 02:36
поделиться

Это расширение GCC , которое означает «если условие истинно, используйте его, иначе используйте это другое значение», поэтому

machine->max_cpus = machine->max_cpus ?: 1;

является сокращением для

machine->max_cpus = machine->max_cpus ? machine->max_cpus : 1;

, хотя если у условного есть побочные эффекты, оно будет запущено только один раз

10
ответ дан 27 November 2019 в 02:36
поделиться

Это расширение GCC , и оно становится более интересным и полезным, когда условие имеет побочные эффекты .

В этом случае, да, я согласен, что это неясно больше всего на свете.

3
ответ дан 27 November 2019 в 02:36
поделиться

Используя флаг gcc -pedantic, он говорит

foo.c: 5: warning: ISO C запрещает опускать средний термин из?: выражение

6
ответ дан 27 November 2019 в 02:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: