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

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

浏览Linux内核源代码时,我发现了一段代码,其中括号括起来的语句块被视为表达式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


海绵宝宝撒
浏览 493回答 2
2回答

茅侃侃

它被称为“表达式中的支撑组”。ANSI / ISO C和C ++都不允许它,但gcc支持它。

白衣染霜花

这是无效的C它是一个gcc名为语句表达式的扩展,你可以在这里找到完整的C扩展列表。这实际上是Linux内核中使用的许多gcc扩展之一,似乎clang也支持这一点,尽管它没有在文档中明确命名。当你观察到最后一个表达式作为表达式的值时,文档说(强调我的):复合语句中的最后一件事应该是一个后跟分号的表达式;&nbsp;此子表达式的值用作整个构造的值。(如果你在大括号中最后使用了一些其他类型的语句,那么构造的类型为void,因此实际上没有值。)其中一个主要好处是制作安全的宏,避免多重评估带有副作用的参数。给出的示例使用此不安全的宏:#define&nbsp;max(a,b)&nbsp;((a)&nbsp;>&nbsp;(b)&nbsp;?&nbsp;(a)&nbsp;:&nbsp;(b))可以使用语句表达式重写其中一个a或b两个并重写以消除此问题,如下所示:#define&nbsp;maxint(a,b)&nbsp;\&nbsp;&nbsp;&nbsp;({int&nbsp;_a&nbsp;=&nbsp;(a),&nbsp;_b&nbsp;=&nbsp;(b);&nbsp;_a&nbsp;>&nbsp;_b&nbsp;?&nbsp;_a&nbsp;:&nbsp;_b;&nbsp;})注意,需要明确使用int哪个可以修复使用另一个gcc扩展名Typeof:#define&nbsp;max(a,b)&nbsp;\&nbsp;&nbsp;&nbsp;({&nbsp;typeof&nbsp;(a)&nbsp;_a&nbsp;=&nbsp;(a),&nbsp;_b&nbsp;=&nbsp;(b);&nbsp;_a&nbsp;>&nbsp;_b&nbsp;?&nbsp;_a&nbsp;:&nbsp;_b;&nbsp;})请注意,clang也支持typeof。
打开App,查看更多内容
随时随地看视频慕课网APP