GCC 对复合语句的评估

GCC evaluation of compound statement

我在驱动程序中发现了以下构造,其中变量被分配给似乎是复合语句的内容 foo。为了进行比较,bar 将相同的代码视为正确的函数会产生未定义的行为。似乎不符合我对C语言及其预处理器的理解,所以怀疑是GCC的扩展。这里执行的逻辑是什么? (见输出 here。)

#include <stdio.h>

#define foo(c) ({ int x = c; x; })

int bar(char c) {
    int x = c;
    x;
}

int main(void) {
    int x = foo('0');
    int y = bar('A');
    printf("%d\n%d\n", x, y);
    return 0;
}

输出:

48
0

这里涉及到两件不同的事情。

首先,所谓的"statement expression" ({ int x = c; x; }),这是一个GCC扩展。 GCC 中的这个表达式的计算结果为 x 的 well-defined 值。它计算的值由 ({...}) 中的最后一个表达式定义,在您的例子中是 x。 (顺便说一句,预处理器与它关系不大。您不必涉及预处理器即可在 GCC 中使用语句表达式。)

其次,你的函数 bar,声明为 return int 但缺少 return 语句。这与任何扩展无关。此函数没有 return 任何定义值。如果调用代码试图使用由 bar 编辑的值 return,则行为未定义。 bar 末尾的 x 表达式只是一个 no-op,不会改变任何东西。

它确实是一个 GCC 扩展,在 GCC manual 中有描述。在需要表达式的地方,您可以提供一个 brace-surrounded 块作为有效表达式,其值是块中的最后一个表达式。

C不会自动在函数末尾的表达式语句中插入一个return,所以bar确实是UB。 GCC 也没有实现任何扩展。但以下内容对于 GCC 扩展是合法的:

int bar(char c) {
  return ({
    int x = c; 
    x; 
  });
}