Practical differences between "do {...} while (0)" and "{...} ((void) 0)" in macros?

Common practice in C:

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

While this is great, it is also possible to do:

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

{...}((void)0) has many advantages: you cannot accidentally combine logic, but at the end of the line is required ; , so odd expressions like this are not noticed: FOO() else {...} .

The only difference I noticed is that you need to use curly braces in if-statements.

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

Must be written as:

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

At the same time, this quirk seems to work well, preventing the same problems that the do/while method is commonly used for.

Are there significant differences between the two methods?

In other words, if you see the code base using {...}((void)0) , are there practical reasons to switch to using do{..}while(0) , besides the fact that one difference is already noted?

+8
c macros syntax
source share
2 answers

The practical difference is exactly what you indicated.

The idiom do { ... } while (0) means that the macro can be used in any context that requires approval.

Your suggested idiom { ... } ((void)0) can be safely used in most contexts that require an expression, but it can fail if it is used in an if declaration.

I can not think of any good reason to use an unfamiliar idiom, which almost always works when the idiom is always well known there.

+6
source share

One difference: you can use break with #define FOO() do { /* body */ } while (0) , but not with #define FOO() { /* body */ }(void)0 .

Let's say you are inside a function, say hello() and do something in #define FOO() do { /*some device operation */ } while (0) , but some error occurred, so you no longer want to continue working with by this device, but there are other operators in the hello() function that you want to execute, say, for another device.

So, if you use the second operator, then you will most likely return a return that comes out of hello() , but if you use the first operator, you can happily break and perform some operation in the same hello() function for another device .

+2
source share