当需要在预处理器宏中执行多条语句时,通常这样写
#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
块现在属于错误的如果。
if
do/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)
。