问题
Possible Duplicate:
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
When one needs to execute multiple statements within preprocessor macro, it's usually written like
#define X(a) do { f1(a); f2(a); } while(0)
so when this macro is used inside expressions like:
if (...)
X(a);
it would not be messed up.
The question is: wherever I've seen such expression, it's always do { ... } while(0);. Is there any reason to prefer such notion over (in my opinion more clear one) if (1) { ... }? Or am I wrong in my observations and they are equally popular?
回答1:
Nope, you're not wrong.
There's actually a nice reason:
#define my_code if (1) { ... }
if (1)
my_code;
The problem is with the ; ! It shouldn't be there... and that would just look strange and not in the spirit of the language. You can either choose to have a code that expands in to two ; in a row, or a code that looks un-c-ish :)
On the other hand, the do-while construction does not have that problem.
Also, as others mentioned, there's an else problem:
if (1)
my_code;
else { ... }
Ignoring the ; issuse, the else block now belongs to the wrong if.
回答2:
if can be as safe as do/while only if there is else branch. E.g.:
#define X(a) if(1) { f1(a); f2(a); } else{}
Is as safe as:
#define X(a) do { f1(a); f2(a); } while(0)
So that the user can't do:
X(...) else ...;
One difference is that when using do/while it requires a ; at the end, whereas if/else doesn't.
回答3:
Consider this:
if(foo)
X(a);
else
whatever();
This would expand to:
if(foo)
if(1) { ... }
else
whatever();
Which is bad because now the else belongs to the wrong if.
回答4:
Using do... while allows you to break out if necessary.
回答5:
When you use #define X(a) do { ... } while(0) form, it forces you to put ; at the end of the statement X(1).
来源:https://stackoverflow.com/questions/10720465/do-while0-vs-if-1-in-macros