问题
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