2011-03-23 17 views
4

通常,在宏中,您会看到人们使用do { ... } while(0)吞下分号。我只是碰到他们使用({ ... })而不是一个例子来,它似乎不仅吞下分号,但似乎让你返回一个值,以及:在宏中使用({...})括号吞下分号

#define NEW_MACRO() ({ int x = 1; int y = 2; x+y; }) 

if(1) 
    val = NEW_MACRO(); 
else 
    printf("this never prints");` 

VAL会出来为3,我可以没有找到任何文件,所以我对此有点谨慎。这个方法有什么问题吗?

+0

这是一个GNU扩展。 – 2011-03-23 18:13:24

+0

如果我记得,它不是标准(只有可能gcc兼容)。 – cobbal 2011-03-23 18:13:51

+1

这段代码不是C,而是“GNU C”。 – 2011-03-23 18:24:31

回答

8

这是无效的标准C.

一些编译器可能具有扩展名(例如GCC的statement expressions),允许这样的事情。

+1

这个特殊符号'({...})'被发明出来了据我所知(至少可以追溯到广泛使用的GCC 2.7.2.3),并且只有希望与GCC的扩展兼容的编译器才能找到,比如英特尔专用的Linux编译器。 – zwol 2011-03-23 18:27:30

+1

+1这也是一种混淆代码的方式,并且使得调试变得更加困难:) – slezica 2011-03-23 18:27:59

0

do { ... } while(0)不适用于“吞咽分号”。它用于将C表达式转换为C语句。

+2

不,这是为了将C语言块变成C语句,这样它就像一个单独的“函数调用”,在包含if '/'else'和'do' /'while'语句。 – 2011-03-23 19:55:07

+0

@R它*用于*无论用户使用它。我已经看到它用于*吞咽分号,它也有你描述的效果。 – 2017-02-16 17:24:37

1

正如Oli所说的,这是gcc发明的。目标是(通常有typeof扩展名)能够仅评估一次宏元素,并稍后通过使用名称使用该计算值。

通过使用inline函数,可以完全避免多次这样的使用。这些也对(类型)的(非)优势更加严格。

在一些其他情况下,您只需要一个临时变量的地址您传递给函数,C99也有复合文字可用于此。

+0

对于“(dis)”+1和使用复合文字代替丑陋的临时变量。 – 2011-03-23 19:55:42