在Linux中奇怪地使用条件运算符

Con*_*yer 37 c linux gcc c99

在3.0.4 Linux内核中,mm/filemap.c有这行代码:

retval = retval ?: desc.error;
Run Code Online (Sandbox Code Playgroud)

我已经尝试用gcc -Wall编译一个类似的最小测试用例,并且没有得到任何警告; 行为似乎与:

retval = retval ? retval : desc.error;
Run Code Online (Sandbox Code Playgroud)

看看C99标准,我无法弄清楚正式描述这种行为的原因.为什么这样好?

zwo*_*wol 36

正如其他几位人士所说,这是GCC扩展,不属于任何标准.如果使用-pedantic开关,您将收到警告.

这个扩展是不是在这种情况下确实明显,但想象一下,如果相反,它是

retval = foo() ?: desc.error;
Run Code Online (Sandbox Code Playgroud)

随着扩展,foo()只被调用一次.没有它,你必须引入一个临时变量来避免调用foo()两次.

  • 但是retval = foo(); retval = retval?retval:desc.error; 更好,100%便携. (13认同)

Dav*_*ven 19

这是一个gcc扩展.x ?: y等同于x ? x : y---见http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals.

是的,我认为这也是邪恶的.

  • @Zack:它很邪恶,因为它让那些不知道非便携和不必要语法的人感到困惑. (8认同)
  • 这不是*邪恶.对于可空类型,它有点等同于C#的`??`运算符. (3认同)
  • @zzzzBov:我明白了。我只是想表明,我并不觉得它本身是邪恶的 __ 本身__,但我觉得它是邪恶的,因为它是一个让不了解 GNU C 的人感到困惑的扩展。 (2认同)

Dav*_*rtz 7

这是一个名为Conditionals with Omitted Opends的GCC扩展.省略中间操作数具有使用条件的值作为省略的操作数而不再对其进行评估的效果.即使条件是宏,也可以安全使用.