当需要在预处理器宏中执行多条语句时,通常这样写
#define X(a) do { f1(a); f2(a); } while(0)
因此,当在表达式中使用此宏时,例如:
if (...)
X(a);
它不会被搞砸的。
问题是:无论我在哪里看到这样的表达,它总是do { ... } while(0);。有什么理由更喜欢这样的概念(在我看来更清楚)if (1) { ... }?还是我的观察错了,它们同样受欢迎?
当需要在预处理器宏中执行多条语句时,通常这样写
#define X(a) do { f1(a); f2(a); } while(0)
因此,当在表达式中使用此宏时,例如:
if (...)
X(a);
它不会被搞砸的。
问题是:无论我在哪里看到这样的表达,它总是do { ... } while(0);。有什么理由更喜欢这样的概念(在我看来更清楚)if (1) { ... }?还是我的观察错了,它们同样受欢迎?
不,你没有错。
其实有一个很好的理由:
#define my_code if (1) { ... }
if (1)
my_code;
问题在于;!它不应该在那里......这看起来很奇怪,而且不符合语言的精神。您可以选择将代码;连续扩展为两个,也可以选择看起来非 c-ish的代码:)
另一方面,do-while建筑没有这个问题。
另外,正如其他人提到的,还有一个else问题:
if (1)
my_code;
else { ... }
忽略;问题,该else块现在属于错误的如果。
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而不需要。
考虑一下:
if(foo)
X(a);
else
whatever();
这将扩展为:
if(foo)
if(1) { ... }
else
whatever();
这很糟糕,因为现在 else 属于错误的 if。
使用do... while允许您break在必要时退出。
当您使用#define X(a) do { ... } while(0)表单时,它会强制您放在;语句的末尾X(1)。