我之前认为这是不可能的,但显然在 Objective-C 中是被允许的:
int a = b ?: c;
所以你看到他们在这里做的是,他们省略了三元表达式的第二部分,这样如果b非零,则使用b作为第二部分。
这很聪明,但据我所知,这违反了K&R C和可能也违反了ANSI C。
如果没有,多年来我一直错过了一个非常聪明的语法技巧...唉!
更新:这是gcc。
我之前认为这是不可能的,但显然在 Objective-C 中是被允许的:
int a = b ?: c;
所以你看到他们在这里做的是,他们省略了三元表达式的第二部分,这样如果b非零,则使用b作为第二部分。
这很聪明,但据我所知,这违反了K&R C和可能也违反了ANSI C。
如果没有,多年来我一直错过了一个非常聪明的语法技巧...唉!
更新:这是gcc。
来源于http://en.wikipedia.org/wiki/%3F%3A
C语言的GNU扩展允许省略第二个操作数,自动使用第一个操作数作为第二个操作数:
a = x ? : y;
该表达式等价于
a = x ? x : y;
但是,如果x是一个表达式,它只会被评估一次。如果评估这个表达式有副作用,这种差异是显著的。
这种行为在gcc
和clang
中都有定义。如果您正在构建 macOS 或 iOS 代码,没有理由不使用它。
但是,在可移植代码中,我不会轻易使用它,需要仔细考虑。
$ cat > foo.c
#include <stdio.h>
int main(int argc, char **argv)
{
int b = 2;
int c = 4;
int a = b ?: c;
printf("a: %d\n", a);
return 0;
}
$ gcc -pedantic -Wall foo.c
foo.c: In function ‘main’:
foo.c:7: warning: ISO C forbids omitting the middle term of a ?: expression
所以,不允许这样做。在这种情况下,gcc发出的是:
$ ./a.out
a: 2
因此,未定义的行为会执行您在问题中提到的操作,即使您不想依赖它。