ANSI C中的parens表达式包含复合语句(块)吗?

时间:2009-08-06 10:06:22

标签: c gcc standards expression

浏览Linux内核源我发现some piece of code,其中括号括起来的语句块被视为表达式 a la lisp (或ML),即表达式的值是最后一个陈述的价值。

例如:

int a = ({
    int i;
    int t = 1;
    for (i = 2; i<5; i++) {
        t*=i;
    }
    t;
});

我一直在看ANSI C grammar试图找出这段代码如何适合解析树,但我没有成功。

那么,是否有人知道这种行为是由标准规定还是只是GCC的特殊性?

更新:我尝试使用标记-pedantic,编译器现在给我一个警告:

warning: ISO C forbids braced-groups within expressions

2 个答案:

答案 0 :(得分:32)

它被称为“表达式中的支撑组”。

ANSI / ISO C和C ++不允许这样做,但gcc支持它。

答案 1 :(得分:31)

这是无效的C它是名为statement expressionsgcc扩展名,您可以找到C扩展名here的完整列表。这实际上是many gcc extensions used in the Linux kernel中的一个,看起来像clang supports this too,虽然它未在文档中明确命名。

当您观察到最后一个表达式作为表达式的值时,文档说(强调我的):

  

复合语句中的最后一项应该是一个后跟分号的表达式;此子表达式的值用作整个构造的值。 (如果你在大括号中最后使用了一些其他类型的语句,那么构造的类型为void,因此实际上没有值。)

主要好处之一是制作安全宏,避免多次评估带副作用的参数。给出的示例使用此不安全的宏:

#define max(a,b) ((a) > (b) ? (a) : (b))

两次评估ab,可以使用语句表达式重写以消除此问题,如下所示:

#define maxint(a,b) \
   ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) 

请注意,需要明确使用可以使用其他int分机Typeof修复的gcc

#define max(a,b) \
   ({ typeof (a) _a = (a), _b = (b); _a > _b ? _a : _b; }) 

请注意clang also supports typeof