5

可能重复:
为什么在 C/C++ 宏中有时会出现无意义的 do/while 和 if/else 语句?

当需要在预处理器宏中执行多条语句时,通常这样写

#define X(a) do { f1(a); f2(a); } while(0)

因此,当在表达式中使用此宏时,例如:

if (...)
    X(a);

它不会被搞砸的。

问题是:无论我在哪里看到这样的表达,它总是do { ... } while(0);。有什么理由更喜欢这样的概念(在我看来更清楚)if (1) { ... }?还是我的观察错了,它们同样受欢迎?

4

5 回答 5

9

不,你没有错。

其实有一个很好的理由:

#define my_code if (1) { ... }

if (1)
    my_code;

问题在于;!它不应该在那里......这看起来很奇怪,而且不符合语言的精神。您可以选择将代码;连续扩展为两个,也可以选择看起来非 c-ish的代码:)

另一方面,do-while建筑没有这个问题。


另外,正如其他人提到的,还有一个else问题:

if (1)
    my_code;
else { ... }

忽略;问题,该else块现在属于错误的如果。

于 2012-05-23T13:04:47.240 回答
7

ifdo/while只有有else分支才能安全。例如:

#define X(a) if(1) { f1(a); f2(a); } else{}

与以下一样安全:

#define X(a) do { f1(a); f2(a); } while(0)

这样用户就不能这样做:

X(...) else ...;

一个区别是,当使用do/while它时,最后需要 a ;if/else而不需要。

于 2012-05-23T13:03:43.000 回答
5

考虑一下:

if(foo)
    X(a);
else
    whatever();

这将扩展为:

if(foo)
    if(1) { ... }
else
    whatever();

这很糟糕,因为现在 else 属于错误的 if。

于 2012-05-23T13:04:55.497 回答
2

使用do... while允许您break在必要时退出。

于 2012-05-23T13:04:09.307 回答
2

当您使用#define X(a) do { ... } while(0)表单时,它会强制您放在;语句的末尾X(1)

于 2012-05-23T13:04:20.967 回答