在宏中执行{} while(0)与if(1){}

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

当需要在预处理器宏中执行多个语句时,它通常被编写为

#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; 

问题在于; ! 它不应该存在……那只会看起来很奇怪,而不是语言的精神。 您可以选择将代码扩展为两个; 连续,或代码看起来un-c-ish 🙂

另一方面, do-while构造没有那个问题。


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

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

无视; 在issuse中, else块现在属于错误的if。

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时需要一个; 最后,而if/else则没有。

考虑一下:

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

这将扩展到:

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

哪个是坏的,因为现在其他属于错误的if。

使用do... while允许你在必要时break

当你使用#define X(a) do { ... } while(0)forms时,会强迫你放置; 在声明X(1)的末尾。