分配语句的结果,后跟表达式和分号

时间:2017-04-28 11:16:23

标签: c

对不起,我不能正确地说出这些事情,如果可以的话,我可能不必问。 由于分号,后一部分可能也是一个陈述,但它只是一个“a + b”,它没有做任何事情?

我最近看到了这个帖子及其接受的答案: MIN and MAX in C

使用此宏:

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

我检查它以了解它是如何工作的,即如何产生一些东西,在宏观扩展时,可以分配给其他东西。 所以这里有一个更简单的例子,它可以编译并完成它的工作:

int x = ({ int a=5; int b=3; a + b; });
printf( "%i", x );
// output: 8

为什么/如何完全正常工作,以及为什么编译/工作需要两个大括号({})?

3 个答案:

答案 0 :(得分:3)

这是一个名为statement expression的GCC功能。它不是标准C的一部分。

它可以推断 - 表达式中的代码运行,然后表达式求值为其中最后一个语句的值。

({})是必要的,因为这是GCC的创造者决定的 - 可能是因为它不可能与其他任何东西混淆。

答案 1 :(得分:2)

这是GCC-specific extension。它不符合标准,并且不太可能在大多数编译器中工作。我想它不必要求那些括号,但是让它们在视觉上更明显,并且使其无意中使用的可能性降低。

默认情况下,GCC允许非标准扩展而无需任何诊断 - 如果您使用说-std=c11 -pedantic编译,您将获得

% gcc -std=c11 -pedantic foo.c
foo.c: In function ‘main’:
foo.c:4:12: warning: ISO C forbids braced-groups within expressions [-Wpedantic]
    int x = ({ int a=5; int b=3; a + b; });
            ^

答案 2 :(得分:1)

这是一个所谓的Statement Expression,不符合标准。

回想一下,C有语句和表达式。语句在不产生值的情况下执行,而表达式总是在最后产生值。

C允许表达式从头开始用作语句。但是,没有语法来表达语句。

GCC扩展恢复了对称性:当您在括号中包含花括号,并在语句块的末尾有一个表达式时,gcc将其作为有效表达式。这个技巧允许你在语句中进行声明,但你可以将任何其他表达式放在花括号中,例如

int x = ({
    int i = 0;
    for (int j = 0 ; j != 6 ; j++) {
        i += j;
    }
    i; // <<== This expression serves as a "return" for the statement
});
printf("%d\n", x);

在上面,整个for循环是变量x的单个初始化表达式的一部分。

This program prints 15.