GCC评估复合陈述

时间:2017-02-03 00:10:04

标签: c gcc c-preprocessor gcc-statement-expression

我找到了以下构造,其中变量被分配给驱动程序中似乎是复合语句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

2 个答案:

答案 0 :(得分:2)

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

首先,所谓的“语句表达式”({ int x = c; x; }),这是一个GCC扩展。 GCC中的此表达式评估为明确定义的x值。它评估的值由({...})中的最后一个表达式定义,在您的情况下为x。 (顺便说一句,预处理器与它没什么关系。你不必让预处理器在GCC中使用语句表达式。)

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

答案 1 :(得分:2)

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

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

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