ANSI C 中的复合语句(块)是否被括号表达式包围?
浏览Linux内核源代码我发现一些片段代码,其中括号括起来的语句块被视为表达式 a la lisp(或 ML),即,其值是最后一个语句的值的表达式。
例如:
int a = ({
int i;
int t = 1;
for (i = 2; i<5; i++) {
t*=i;
}
t;
});
我一直在查看 ANSI C 语法 试图弄清楚这段代码如何适合解析树,但我还没有成功。
那么,有人知道这种行为是标准强制的还是只是 GCC 的一个特性?
更新:我尝试过使用 -pedantic 标志,编译器现在给了我一个警告:
warning: ISO C forbids braced-groups within expressions
Browsing the Linux kernel sources I found some piece of code where a block of statements surrounded by parenthesis is treated as a expression a la lisp (or ML), that is, an expression which value is the value of the last statement.
For example:
int a = ({
int i;
int t = 1;
for (i = 2; i<5; i++) {
t*=i;
}
t;
});
I've been looking at the ANSI C grammar trying to figure out how this piece of code would fit in the parse tree, but I haven't been successful.
So, does anybody know if this behaviour is mandated by the standard or is just a peculiarity of GCC?
Update: I've tried with the flag -pedantic and the compiler now gives me a warning:
warning: ISO C forbids braced-groups within expressions
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是标准的 C。它是一个名为 语句表达式 的 gcc 扩展。 您可以在此处找到 C 扩展的完整列表。 这实际上是 Linux 内核中使用的许多 gcc 扩展之一似乎 clang 也支持这个尽管文档中没有明确命名。
正如您所观察到的,最后一个表达式充当表达式的值,文档中写道(强调我的):
主要好处之一是制作可以避免多次求值的安全宏具有副作用的参数。 给出的示例使用了这个不安全的宏:
它计算
a
或b
两次,并且可以使用语句表达式重写以消除此问题,如下所示:注意,需要显式使用
int
可以使用另一个gcc
扩展来修复 Typeof:请注意 clang 也支持typeof。
This is not standard C. It is a gcc extension called statement expressions. You can find the complete list of C extensions here. This is actually one of the many gcc extensions used in the Linux kernel and it seems like clang supports this too and although it is not explicitly named in the document.
As you observed the last expression serves as the value of the expression, the document says (emphasis mine):
One of the main benefits would be to make safe macros that would avoid multiple evaluations of arguments with side effects. The example given uses this unsafe macro:
which evaluates either
a
orb
twice and can be rewritten to eliminate this problem using statement expressions as follows:Note, the need to explicitly use
int
which can fixed using anothergcc
extension Typeof:Note that clang also supports typeof.
它被称为“表达式内的支撑组”。
ANSI/ISO C 和 C++ 都不允许这样做,但 gcc 支持它。
It's called "braced-group within expression".
It's not allowed by ANSI/ISO C nor C++ but gcc supports it.