ANSI C中parensexpression式包围的复合语句(块)?

浏览Linux内核源代码我发现了一些代码 ,其中由括号括起来的语句块被当作一个expression式来处理,也就是说,一个expression式的值是最后一个语句的值。

例如:

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

我一直在研究ANSI C语法,试图弄清楚这段代码如何适合parsing树,但是我还没有成功。

那么,有没有人知道这个行为是由这个标准规定还是只是GCC的一个特点?

更新:我已经试过用flag -pedantic,编译器现在给我一个警告:

 warning: ISO C forbids braced-groups within expressions 

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

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

这是一个叫做语句expression式的gcc扩展,你可以在这里find完整的C扩展列表。 这实际上是Linux内核中使用的许多gcc扩展中的一个,看来clang也支持这个 扩展 ,尽pipe它在文档中没有明确的命名。

正如你所观察到的,最后一个expression式是expression式的价值,文件说( 强调我的 ):

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

其中一个主要的好处是可以制作安全的macros,避免对副作用进行多次评估。 给出的例子使用这个不安全的macros:

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

它评估ab两次,可以重写,以消除这个问题,使用语句expression式如下:

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

注意,需要显式地使用int ,可以使用另一个gcc扩展来修复Typeof :

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

请注意, clang也支持typeof 。