宏中"do {...} while(0)"和"{...}((void)0)"之间的实际差异?

ide*_*n42 8 c syntax macros

在C中使用的常见做法是:

#define FOO() do { /* body */ } while (0)
Run Code Online (Sandbox Code Playgroud)

虽然这很好,但也可以这样做:

#define FOO() { /* body */ }((void)0)
Run Code Online (Sandbox Code Playgroud)

{...}((void)0)有许多相同的好处:你不能意外地合并逻辑,并且;在行的末尾需要a ,所以像这样的奇怪表达不会被注意到:FOO() else {...}.

我注意到的唯一区别是它意味着你需要在if语句中使用大括号.

if (a)
    FOO();
else
    BAR();
Run Code Online (Sandbox Code Playgroud)

必须写成:

if (a) {
    FOO();
} else {
    BAR();
}
Run Code Online (Sandbox Code Playgroud)

除了这个怪癖之外,它似乎运作良好,防止了do/while通常使用的同类问题方法.

两种方法之间是否存在显着差异?

换句话说,如果您看到使用代码库{...}((void)0),是否有切换到使用的实际原因do{..}while(0),除了已经注意到的一个区别?

Kei*_*son 7

实际差异正是你所指出的.

do { ... } while (0)成语的意思是,宏可以用在任何需要的声明内容.

您建议的习惯用法{ ... } ((void)0)可以在大多数需要表达式的上下文中安全使用- 但如果它在unbraced if语句中使用它可能会失败.

我认为没有什么理由使用不熟悉的成语几乎总是工作,当有一个众所周知的成语总是有效.

  • 有一种情况它不起作用 - 当你想在宏中使用`break`时(虽然不是经常做的事情). (2认同)