在什么版本的C中,括号内的块用于返回有效值?

如果我做:

int j = ({int x = 7; x+3;}); 

在i686-apple-darwin10-gcc-4.2.1(GCC)4.2.1(Apple Inc. build 5646)gcc它编译得很好。 有问题的块({int x = 7; x+3;})返回最后一个语句的值作为块的值。 如果删除括号,则无法编译。 我能指望这在大多数C编译器中都能使用吗?

另外,这个结构的名称是什么? 我在搜索它时遇到了很多麻烦,因为搜索引擎没有索引(){}而C是一个糟糕的搜索词。 我也无法在任何书中找到任何关于它的内容,可能是因为我不知道该找什么。

如果删除括号,则无法编译。

如果没有括号,编译器会将其视为聚合初始化块,并在看到int关键字时失败。 初始化程序块中不能包含关键字。

6.7.8初始化

11标量的初始值设定项应为单个表达式,可选择用大括号括起来。 对象的初始值是表达式的初始值(转换后); 与简单赋值相同的类型约束和转换适用,将标量的类型作为其声明类型的非限定版本。

6.2.5类型

算术类型和指针类型统称为标量类型。 数组和结构类型统称为聚合类型。


我可以期望这在大多数c编译器中都能使用吗?

不。看起来像非标准的GNU扩展。

另外,这个结构的名称是什么?

我想知道是否有。 实际上,这与宏通常做的类似。

这是GCC扩展 :

括在括号中的复合语句可能在GNU C中显示为表达式。这允许您在表达式中使用循环,开关和局部变量。

回想一下复合语句是由大括号包围的一系列语句; 在这个结构中,括号围绕括号。 例如:

  ({ int y = foo (); int z; if (y > 0) z = y; else z = - y; z; }) 

对于foo ()的绝对值,它是一个有效的(虽然比必要的稍微复杂一些)表达式。

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

您可以期望它适用于大多数GCC版本。

你可以期待它几乎无处可去 – 它是一个GCC扩展。

GCC手册中描述该function的部分标题为“表达式中的语句和声明”:

括在括号中的复合语句可能在GNU C中显示为表达式。

后来它说:

在语句表达式中的语句内创建的任何临时语句都将在语句结束时销毁。 这使得宏中的语句表达式与函数调用略有不同。

因此,’statement expression’似乎是文档中使用的名称。