简体   繁体   English

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

[英]Practical differences between “do {…} while (0)” and “{…} ((void)0)” in macros?

It's common practice in C to use: 在C中使用的常见做法是:

#define FOO() do { /* body */ } while (0)

While this is fine, it's also possible to do: 虽然这很好,但也可以这样做:

#define FOO() { /* body */ }((void)0)

{...}((void)0) has many of the same benefits: you can't accidentally merge logic, and a ; {...}((void)0)有许多相同的好处:你不能意外地合并逻辑,和; is required at the end of the line, so odd expressions like this don't go by un-noticed: FOO() else {...} . 在行的末尾需要,所以像这样的奇怪表达不会被注意到: FOO() else {...}

The only difference I've noticed is it means you need to use braces in if-statements. 我注意到的唯一区别是它意味着你需要在if语句中使用大括号。

if (a)
    FOO();
else
    BAR();

Must be written as: 必须写成:

if (a) {
    FOO();
} else {
    BAR();
}

Other then this quirk, it seems to work well, preventing the same kinds of problems do/while method is typically used for. 除了这个怪癖,它似乎运作良好,防止同样的问题do/while通常使用方法。

Are there any significant differences between the 2 methods? 两种方法之间是否存在显着差异?

Said differently , if you see a code-base using {...}((void)0) , are practical reasons to switch to using do{..}while(0) , besides the one difference already noted? 换句话说 ,如果你看到使用{...}((void)0)的代码库,那么切换到使用do{..}while(0)实际原因除了已经注意到的一个区别外?

The practical difference is exactly what you pointed out. 实际差异正是你所指出的。

The do { ... } while (0) idiom means that the macro can be used in any context that requires a statement. do { ... } while (0)惯用语意味着宏可以在任何需要语句的上下文中使用。

Your suggested idiom { ... } ((void)0) can be used safely in most contexts that require an expression -- but it can fail if it's used in an unbraced if statement. 您建议的习惯用法{ ... } ((void)0)可以在大多数需要表达式的上下文中安全使用 - 但如果它在unbraced if语句中使用它可能会失败。

I can think of no good reason to use an unfamiliar idiom that almost always works, when there's a well known idiom that always works. 我认为没有什么理由使用不熟悉的成语, 几乎总是工作,当有一个众所周知的成语永远奏效。

One difference is you can use break with #define FOO() do { /* body */ } while (0) but not with #define FOO() { /* body */ }(void)0 . 一个区别是你可以使用#define FOO() do { /* body */ } while (0)而不使用#define FOO() { /* body */ }(void)0

Let's say you are inside a function, say hello() , and doing something in #define FOO() do { /*some device operation */ } while (0) but some error occurred so you no longer want to proceed with that device but there are other statements in function hello() you want to execute, let's say for another device. 假设你在一个函数里面,比如hello() ,并且在#define FOO() do { /*some device operation */ } while (0)但是发生了一些错误,因此您不再需要继续使用该设备但是你想要执行的函数hello()还有其他语句,比方说另一个设备。

So if you use second statement then you will do return most probably which will exit out of hello() but if you use the first statement you can happily break and do some operation in same function hello() for another device. 因此,如果您使用第二个语句,那么您将返回最可能将退出hello()但是如果您使用第一个语句,则可以愉快地break并在同一函数hello()为另一个设备执行某些操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM