admin管理员组

文章数量:1278790

I have read in some other questions here why do { } while (0) is good for function-like macros in C. Also, this form provides the break instruction in order to simulate a return statement.

But in those other questions, I never read anything "clear" about if (1) { } else.

For me, this is almost equal to do { } while (0) with the difference being that here we don't have the break statement.

And I guess it’s better than if (1) { } else { } because it allows us to use ;.

Is it really "safe"? Are there any reasons for choosing this over do { } while (0)?

I have read in some other questions here why do { } while (0) is good for function-like macros in C. Also, this form provides the break instruction in order to simulate a return statement.

But in those other questions, I never read anything "clear" about if (1) { } else.

For me, this is almost equal to do { } while (0) with the difference being that here we don't have the break statement.

And I guess it’s better than if (1) { } else { } because it allows us to use ;.

Is it really "safe"? Are there any reasons for choosing this over do { } while (0)?

Share Improve this question edited Feb 24 at 18:49 TylerH 21.1k77 gold badges79 silver badges112 bronze badges asked Feb 24 at 0:23 proprogrammerproprogrammer 631 silver badge5 bronze badges 11
  • OT: I'll just add that I like & use all those variants you mentioned, but with warnings set high, I do get a warning about "constant used in conditional statement." Pretty sure that it's innocuous so long as that is your intention (to use a constant). But let's see what the SO community says. – greg spears Commented Feb 24 at 0:42
  • Seems you can have as many ; as you like these days. You can have ;;;;;;;;;; in your code and it compiles. – pmacfarlane Commented Feb 24 at 0:52
  • 1 @pmacfarlane: an arbitrary number so semicolons between the body of an if statement and an else creates a syntax error. Otherwise, null statements are allowed anywhere in a function and always have been. – Jonathan Leffler Commented Feb 24 at 1:39
  • 1 Note that within a do { … } while (0) loop, ‘continue` behaves the same as break. This doesn't affect the discussion. – Jonathan Leffler Commented Feb 24 at 1:51
  • 1 Please note that you should only use the do { } while(0) trick in macros that need to be widely portable. Otherwise in a quality (and/or MISRA C compliant portable) code base that enforces compound statements {} after each and every if/else, then do-while(0) is bad style since it blocks diagnostics. What is do { } while(0) in macros and should we use it? – Lundin Commented Feb 24 at 8:36
 |  Show 6 more comments

1 Answer 1

Reset to default 11

Consider the alternatives you propose:

#define foo(x) do { /* main part of macro here */ } while (0)
#define foo(x) if (1) { /* main part of macro here */ } else

Both of these serve the purpose that the macro can be written like a function call:

foo(x);

Notably, the semicolon ends the statement, so the macro invocation looks like many other C statements. To somebody experienced in C, it looks odd if there is a line without a semicolon, like:

x = 3;
foo(x)
y = 4;

However, consider if somebody does accidentally write the above, perhaps because they knew foo was a macro and thought it was a whole statement by itself. Then the while form becomes:

x = 3;
do { /* main part of macro here */ } while (0)
y = 4;

This generates a compiler error since it is not valid C grammar (barring weird extensions). In contrast, the if form becomes:

x = 3;
if (1) { /* main part of macro here */ } else
y = 4;

This may compile without an error, since the y = 4; becomes part of the else. So, in this respect, the while form is superior since it catches an error that the if form does not.

本文标签: Is 39if(1) else39 safe for functionlike macros in CStack Overflow