这是三元条件吗?:正确(客观)C 语法?
Posted
技术标签:
【中文标题】这是三元条件吗?:正确(客观)C 语法?【英文标题】:Is this ternary conditional ?: correct (Objective) C syntax? 【发布时间】:2012-02-04 08:14:29 【问题描述】:我认为这是不可能的,但显然在 Objective C 中这是允许的:
int a = b ?: c;
所以你看到他们在这里做了什么,他们省略了三元表达式的第二部分,这样如果 b 不为零,则 b 用作第二部分。
这很聪明,但据我所知,这违反了 K&R C,可能还有 ANSI C。
如果没有,我多年来一直错过了一个非常聪明的语法技巧......唉!
更新: 是 gcc。
【问题讨论】:
哪个编译器? GCC 将其作为扩展,尽管它已被弃用。 更正确的术语是有条件的。三元只是意味着它是一个带有 3 个参数的运算符。 【参考方案1】:gcc
和 clang
都定义了此行为。如果您正在构建 macOS 或 ios 代码,则没有理由不使用它。
不过,如果不仔细考虑,我不会在可移植代码中使用它。
【讨论】:
【参考方案2】:这是GNU C extension。检查编译器设置(寻找 C 风格)。不确定它是否是 Clang 的一部分,我能得到的唯一信息是 this page:
简介
本文档描述了 Clang 提供的语言扩展。除了此处列出的语言扩展之外,Clang 还旨在支持广泛的 GCC 扩展。有关这些扩展的更多信息,请参阅 GCC 手册。
【讨论】:
【参考方案3】:来自http://en.wikipedia.org/wiki/%3F%3A
对 C 的 GNU 扩展允许省略第二个操作数,并隐式使用第一个操作数作为第二个操作数:
a = x ? : y;
表达式等价于
a = x ? x : y;
除了如果 x 是一个表达式,它只计算一次。如果评估表达式有副作用,则差异是显着的。
【讨论】:
【参考方案4】:$ 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
因此,未定义的行为就是按照您在问题中所说的去做,即使您不想依赖它。
【讨论】:
我不喜欢你在这里使用“未定义”这个词。最好称之为非标准; IS 为 GCC 定义的行为,而不是为 ISO C。这使得它对于其他编译器未定义并且不可移植,但它仍然为 GCC 定义。 @steven 问题是它是否是正确的 C 语法,那么无论你的编译器做什么,它在 C 中的未定义行为这一事实都是正确的答案。以上是关于这是三元条件吗?:正确(客观)C 语法?的主要内容,如果未能解决你的问题,请参考以下文章