C中的常见做法是:
#define FOO() do { /* body */ } while (0)
虽然这很好,但也可以这样做:
#define FOO() { /* body */ }((void)0)
{...}((void)0)
有许多相同的好处:你不能意外地合并逻辑,并且在行的末尾需要;
,所以像这样的奇怪表达式不会通过un注意:FOO() else {...}
。
我注意到唯一的区别是它意味着你需要在if语句中使用大括号。
if (a)
FOO();
else
BAR();
必须写成:
if (a) {
FOO();
} else {
BAR();
}
除了这个怪癖之外,它似乎运作良好,可以防止同样的问题do/while
方法通常用于。
两种方法之间是否存在显着差异?
不同地说,如果您看到使用{...}((void)0)
的代码库,那么切换到使用do{..}while(0)
的实际原因是什么,除了已经注意到的一个差异?
答案 0 :(得分:7)
实际差异正如你所指出的那样。
do { ... } while (0)
成语意味着宏可以在需要声明的任何上下文中使用。
您建议的成语{ ... } ((void)0)
可以安全地用于需要表达式的大多数上下文中 - 但如果它在无支撑if
中使用,则可能会失败言。
我认为没有充分的理由使用几乎总是有效的不熟悉的习语,当总是工作时,这是一个众所周知的习语。
答案 1 :(得分:2)
一个区别是您可以使用#define FOO() do { /* body */ } while (0)
中断,但不能使用#define FOO() { /* body */ }(void)0
。
假设你在一个函数内部,比如hello()
,并在#define FOO() do { /*some device operation */ } while (0)
中做了一些事情,但发生了一些错误,所以你不再想继续使用该设备,但函数{{}中还有其他语句1}}你想要执行,让我们说另一个设备。
因此,如果您使用第二个语句,那么您将返回最可能退出hello()
的语句,但如果您使用第一个语句,则可以愉快地hello()
并在同一个函数中执行某些操作{{ 1}}用于其他设备。