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

时间:2012-05-23 13:00:38

标签: c c-preprocessor

  

可能重复:
  Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?

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

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

所以当这个宏用在像:

这样的表达式中时
if (...)
    X(a);

它不会搞砸。

问题是:无论我在哪里见过这样的表达,它总是do { ... } while(0);。有没有理由更喜欢这种观念(在我看来更清楚一点)if (1) { ... }?或者我的观察结果是错误的,它们同样受欢迎?

5 个答案:

答案 0 :(得分:8)

不,你没错。

实际上有一个很好的理由:

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

if (1)
    my_code;

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

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


另外,正如其他人提到的那样,存在else问题:

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

忽略; issuse,else块现在属于错误的if。

答案 1 :(得分:7)

仅当if分支时,

do/while才能与else一样安全。 E.g:

#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则不需要。{/ p>

答案 2 :(得分:4)

考虑一下:

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

这将扩展为:

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

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

答案 3 :(得分:2)

使用do... while可以在必要时break

答案 4 :(得分:2)

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