【问题标题】:Is this ternary conditional ?: correct (Objective) C syntax?这是三元条件吗?:正确(客观)C 语法?
【发布时间】:2012-02-04 08:14:29
【问题描述】:

我认为这是不可能的,但显然在 Objective C 中这是允许的:

int a = b ?: c;

所以你看到他们在这里做了什么,他们省略了三元表达式的第二部分,这样如果 b 不为零,则 b 用作第二部分。

这很聪明,但据我所知,这违反了 K&R C,可能还有 ANSI C。

如果没有,我多年来一直错过了一个非常聪明的语法技巧......唉!

更新: 是 gcc。

【问题讨论】:

  • 哪个编译器? GCC 将其作为扩展,尽管它已被弃用。
  • 更正确的术语是有条件的。三元只是意味着它是一个带有 3 个参数的运算符。

标签: objective-c c ternary-operator conditional-operator


【解决方案1】:

gccclang 都定义了此行为。如果您正在构建 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 中的未定义行为这一事实都是正确的答案。
        猜你喜欢
        • 2021-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多