【问题标题】:Detecting if a C compiler supports statement expressions检测 C 编译器是否支持语句表达式
【发布时间】:2016-12-07 15:50:41
【问题描述】:

有没有办法检测编译器(我有一个拥有它们的当前 GCC 和一个没有它们的老式 clang)是否实现语句表达式,以便我可以执行以下操作:

#ifdef NO_COMPOUND_STATEMENTS
#define MIN(a,b)    ((a)<=(b) ? (a):(b))
#define MAX(a,b)    ((a)>=(b) ? (a):(b))
#else
#define MIN(a,b) ({ __typeof__ (a) _a=(a); __typeof__ (b) _b=(b); _a<_b ? _a : _b; })
#define MAX(a,b) ({ __typeof__ (a) _a=(a); __typeof__ (b) _b=(b); _a>_b ? _a : _b; })
#endif

【问题讨论】:

  • 嗯...“复合语句”? “复合语句”是该语言的一个基本特征,因此自古以来每个 C 编译器都是如此。没有像 C 编译器这样“没有复合语句”的东西。同时,您似乎在谈论语句表达式
  • 你能粘贴一个你的clang编译器不支持的例子吗?
  • 您描述为“复合语句”的功能似乎真的是能够使用复合语句作为表达式。没有任何版本的标准 C 支持这一点;它是 GCC 扩展。可能其他实现也支持它,但没有任何标准方法专门针对它进行测试,因为它本身不是标准的。

标签: c gcc clang


【解决方案1】:

正如 AnT 在他们的回答中所说,它们不是标准的一部分。不幸的是,我在 GCC 中也找不到任何功能测试宏的证据,所以最好的办法是检查以确保您使用的是 C 标准的 gnu 变体和 GCC 版本 3 或更高版本(是添加语句表达式的时间)

#if !__STRICT_ANSI__ && __GNUC__ >= 3
    /* use statement expressions */
#else
    /* use... something else? */
#endif

【讨论】:

    【解决方案2】:

    语句表达式(这似乎是您的问题)不是 C 语言的标准功能。 __typeof__ 也不是,顺便说一句。

    这意味着,如果您想要类似的东西,那么最好的策略可能是手动定义宏,这将允许(或禁止)在代码中使用此类功能。您将为那些实现这些非标准功能的特定编译器手动指定宏。 (基本上就是 GCC。)

    【讨论】:

    • 请注意,标准使用术语“语句表达式”来表示完全不同的东西——用作完整语句的有效表达式。示例:i++;.
    • @John Bollinger:这就是术语“表达语句”。这就是标准所使用的。同时,术语“语句表达”是免费的:)
    • 嗯。您似乎是正确的,尽管脚注 84 实际上确实使用“语句表达式”作为表达式语句。可以将其称为(非规范性)脚注文本中的缺陷。无论如何,如果您得出这种区别,那么我认为您是在创造一个术语。 The GCC docs 似乎没有为这种表达式指定名称。既然如此,我希望你能选择一个不太容易与“表达式语句”混淆的。
    • 复合表达式?
    • @JohnBollinger:我当然不是这个词的创始人。即使 GCC 有时似乎偏离了这个命名法,它仍然在 GCC 文档中广泛使用:gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html(通读全文)。我认为这个词是 GCC 专门创造的,而不是我自己创造的。
    【解决方案3】:

    我会像 autoconf 那样做:如果编译成功,尝试编译一个块并将宏定义输出到您的 config.h(或您拥有的任何东西)中:

    echo 'int main(){ int x = ({ puts(""); 32; }); return x; }' > tmp.c
    if cc -c tmp.c; then  #-c only to save on linking time
       echo '#define HAVE_STMT_EXPR 1'
    fi
    

    【讨论】:

    • 我的玩具项目也依赖于语句表达式。我决定不支持 gcc、clang 和 tinycc 以外的编译器(这三个编译器都有 typeof 和语句表达式)。
    猜你喜欢
    • 2011-09-20
    • 1970-01-01
    • 2014-10-22
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    相关资源
    最近更新 更多