-1

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

#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
4

2 回答 2

2

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

首先,所谓的“语句表达式” ({ int x = c; x; }),它是 GCC 的扩展。GCC 中的这个表达式的计算结果是明确定义的值x。它计算的值由 中的最后一个表达式定义,({...})x您的情况下。(顺便说一句,预处理器与它几乎没有关系。您不必涉及预处理器即可在 GCC 中使用语句表达式。)

其次,您的 function bar,它被声明为 returnint但缺少 return 语句。这与任何扩展无关。此函数不返回任何定义的值。如果调用代码尝试使用 的返回值bar,则行为未定义。x末尾的表达式bar只是一个不会改变任何东西的空操作。

于 2017-02-03T00:16:24.407 回答
2

它确实是 GCC 扩展,在GCC 手册中有描述。在需要表达式的地方,您可以提供一个大括号括起来的块作为有效表达式,其值是块中的最后一个表达式。

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

int bar(char c) {
  return ({
    int x = c; 
    x; 
  });
}
于 2017-02-03T00:19:28.880 回答