【问题标题】:do { } while(0) vs. if (1) { } in macros [duplicate]do { } while(0) vs. if (1) { } 在宏中[重复]
【发布时间】:2012-05-30 00:46:19
【问题描述】:

可能重复:
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) { ... }更喜欢这样的概念(在我看来更清楚)?还是我的观察有误,它们同样受欢迎?

【问题讨论】:

  • #define ever (;;) 然后for ever { ... }
  • @KingsIndian 您链接到的 Q 询问 为什么 存在这样的陈述。 aland here 想知道为什么一个比另一个更可取,我认为这是一个完全有效的问题,也是不同的问题。
  • @penelope 此外,如果我说 dup,那么它不会马上变成 dup。 At least 4 other people have to agree with me 如果社区认为所有 5 位接近投票者都错了,它也可以重新打开。

标签: c c-preprocessor


【解决方案1】:

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 (condition) X(a) 而不使用 ;,它不会强制用户结束他的语句,从而产生有线非分号-编辑代码
  • 我想说if{}else{} 更通用,因为它可以与; 一起使用,也可以不与; 一起使用。就我个人而言,我不喜欢看起来像普通代码的宏,所以我更喜欢在宏之后没有;
  • 我接受佩内洛普的回答,因为它涵盖了两个有问题的案例之间的差异。无意冒犯。
  • 别担心,这是你的问题。
  • 如果X(a) 使用if(1){..}else{} 表单,我认为if (x) X(a); else doSomethingElse(); 不会起作用,但它可以与do{...}while(0) 表单一起使用。
【解决方案2】:

不,你没有错。

其实有一个很好的理由:

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

if (1)
    my_code;

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

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


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

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

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

【讨论】:

    【解决方案3】:

    考虑一下:

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

    这将扩展为:

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

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

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      使用do... while 可以让您在必要时将break 退出。

      【讨论】:

      • 突破什么?他想使用/不使用do-while 作为
      • 如有必要,尽早打破宏的主体。它在 linux 源代码中随处可见。
      • 对我来说,一个半香的解释看起来有点令人困惑和不令人信服。你能添加一个代码 sn-p 来证明你的观点吗?
      猜你喜欢
      • 2010-11-07
      • 2013-10-07
      • 1970-01-01
      • 2012-03-18
      • 2021-04-14
      • 2012-11-25
      • 2010-10-29
      相关资源
      最近更新 更多