为什么不使用三元运算符而不为"true"条件赋值(x = x?:1)

Ric*_*red 39 c gcc qemu conditional-operator android-emulator

在Android开源qemu代码中,我遇到了这行代码:

machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
Run Code Online (Sandbox Code Playgroud)

这只是一种令人困惑的说法:

if (machine->max_cpus) {
   ; //do nothing
} else {
 machine->max_cpus = 1;
}
Run Code Online (Sandbox Code Playgroud)

如果是这样,那就不会更清楚了:

if (machine->max_cpus == 0) machine->max_cpus = 1;
Run Code Online (Sandbox Code Playgroud)

有趣的是,这可以编译并与gcc一起使用,但不能在http://www.comeaucomputing.com/tryitout/上编译.

Uri*_*Uri 50

这在GNU中是允许的,是C的一个模糊扩展

5.7具有省略操作数的条件

可以省略条件表达式中的中间操作数.然后,如果第一个操作数非零,则其值为条件表达式的值.

因此,表达

 x ? : y
Run Code Online (Sandbox Code Playgroud)

如果非零,则其值为x; 否则,y的值.

这个例子完全等同于

 x ? x : y
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,省略中间操作数的能力并不是特别有用.当它变得有用时是第一个操作数,或者可能(如果它是一个宏参数),包含副作用.然后在中间重复操作数将执行两次副作用.省略中间操作数使用已经计算的值而没有重新计算它的不良影响.

正如您可能猜到的那样,出于可读性和可移植性的原因,建议不要这样做.老实说,我很惊讶地看到这种语法不兼容的扩展.

  • 嘿,这就是`||`应该如何工作. (13认同)
  • 有趣.这看起来既非常有用,又作为一种语法特征,并且难以理解. (5认同)
  • interresting.那变成了?在C#"x如果x不为空,否则y"=> c ?? ÿ (3认同)
  • 由于这个成语与"三元条件"不同,而且在大多数语言中更像是"逻辑"或"`",因此我建议将其称为"ternarator". (3认同)
  • @Potatoswatter:不是真的,因为大概是`max_cpus`不是布尔值.如果先前值为"3",`||`无法评估为'3`. (2认同)

Mic*_*zek 10

这是一个GCC扩展,意思是"如果条件为真,则使用它,否则使用其他值",所以

machine->max_cpus = machine->max_cpus ?: 1;
Run Code Online (Sandbox Code Playgroud)

是简写

machine->max_cpus = machine->max_cpus ? machine->max_cpus : 1;
Run Code Online (Sandbox Code Playgroud)

虽然如果条件有副作用,它只会运行一次


Lar*_*olm 6

确实如此,使用gcc的-pedantic标志

foo.c:5:警告:ISO C禁止省略?:表达式的中间项