Why the usage of while(0)

  • Thread starter Riccardo Manfrin
  • Start date
R

Richard Bos

|
| [This shoudl be a FAQ but I can't currently check since the C FAQ site
| appears to be down.]

It is. 10.4 in the text version on my computer.
|> Having this code:
|> do {
|> if (flag_prg)
|> printf("%-" PROGNAME_WIDTHs "s"," " PROGNAME_BANNER);
|> } while (0)
|>
|> why the use of while?
|
| As you present it, none. In fact it's a syntax error since there is
| no ; after the while (0). This is a big clue that the code comes
| from a macro.
|
| The purpose of the loop is syntactic. It encloses the 'if' in a
| statement (when the ; is added by the macro invocation) so that no
| surprises happen to the users of the macro. Consider the simpler:
|
| #define PRINT_BANNER if (flag_prg) \
| printf("%-" PROGNAME_WIDTHs "s"," " PROGNAME_BANNER)
|
| and a usage like this:
|
| if (first_run)
| PRINT_BANNER;
| else puts("Going again...";
|
| The 'else' will be taken to be part of the inner if regardless of the
| indentation. do {} while (0) gets round this and other potentials
| problems with macros that expand to statements.

Do you have an example where enclosing in plain { } is not good enough?

Yes: the one above. If you wrote

#define PRINT_BANNER { statements... }

then

if (first_run)
PRINT_BANNER;
else
puts("Going again...");

would result in

if (first_run)
{ statements... };
else
puts("Going again...");

which, because of the extra semicolon, is a syntax error.

If, OTOH, you write

#define PRINT_BANNER do { statements... } while (0)

then

PRINT_BANNER;

is a single, valid statement, which will run once and only once, in any
context where a normal single-line statement would have done so -
including the above if-else statement (try it!).

Richard
 
A

army1987

#define MACRO do{X}while(0)

This makes X be the body a compound statement, and it forces MACRO to be
semicolon terminated like a simple statement whenever MACRO is used.

MACRO;
If you use
#define MACRO (flag_prg ? printf("%-" PROGNAME_WIDTHs "s"," "
PROGNAME_BANNER) : 0)
you can also use it where you need an expression, e.g. in the
‘initialization’ of a for loop.
 
M

Michael Tsang

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Flash said:
I will use goto sometimes, mainly for exception handling.

I uses goto for jumping out of multi-level loops (for the purpose of Java's
labelled breaks or continues).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAksjrm4ACgkQG6NzcAXitM9dxQCdHMWx5hIgVR78vq/72aA0qySd
WTgAnRKby8ldSku3+KMfDU1ZdKK7uhtI
=MyJQ
-----END PGP SIGNATURE-----
 
T

Tim Rentsch

James Dow Allen said:
[snip]

But anyway, this particular usage of
do {
... break;
... continue;
} while (0);
to avoid 'goto commoncase;' is uninteresting compared
to the goto in
http://james.fabpedigree.com/gotoalt.htm

I must post a correction here. The code attributed to
me on this page is not something I wrote. I did write
something on a related subject (in c.l.c IIRC), but
that was written for a different context. No poor
reflection on James intended, I'm sure it was an honest
mistake; but I need to set the record straight that
the writing isn't mine nor was I intending to make
comments in the context this web page provides.
 
J

James Dow Allen

I must post a correction here. The code attributed to
me on this page is not something I wrote.

Tim posted pseudo-code several years ago in Usenet message
(e-mail address removed)
known to Google via
http://groups.google.com/group/comp.lang.c/msg/d2882f5a6bb1b999?dmode=source

This pseudo-code was specifically in response to my webpage
code. I did edit it slightly (I hope Tim will
point out which change he objects to; glancing at it
now I see little change beyond white space and
capitalization rearrangements.) I mentioned to Tim,
via e-mail, that I intended to post the code; and did
not receive any objection from Tim. This was almost 5
years ago. I can't fault Tim's memory: I barely remember
what I had for brerakfast yesterday! :)

What *is* true, of course, is that in the comments
on my page I defended my approach over Tim's.

I *am* disappointed that no one else has bothered to
"vote" for one approach over the other. The vote
still stands at 1-1 ....

I will remove the code or the attribution at Tim's request.
(I hunted to find parts of my e-mail exchange with Tim which
was at a Yahoo e-mail I use no more. My present e-mail
is jamesdowallen at Gmail.)

Thank you.
James Dow Allen
 
T

Tim Rentsch

James Dow Allen said:
Tim posted pseudo-code several years ago in Usenet message
(e-mail address removed)
known to Google via
http://groups.google.com/group/comp.lang.c/msg/d2882f5a6bb1b999?dmode=source

This pseudo-code was specifically in response to my webpage
code.

No, it was a response to comments and discussion in the thread in
comp.lang.c. It's true that some code that James wrote formed
the backdrop for my comments, but they really were directed at
the newsgroup discussion and goto's/backtracking generally, not
meant as commentary on James's code.
I did edit it slightly (I hope Tim will
point out which change he objects to; glancing at it
now I see little change beyond white space and
capitalization rearrangements.) I mentioned to Tim,
via e-mail, that I intended to post the code; and did
not receive any objection from Tim. This was almost 5
years ago. I can't fault Tim's memory: I barely remember
what I had for brerakfast yesterday! :)

I think you are misremembering. We did trade some emails about
the possibility of my providing some code for that purpose, but I
never did provide any such code, and I'm sure I would have raised
an objection if I thought something was going to be put up other
than something I specifically provided for that purpose.
What *is* true, of course, is that in the comments
on my page I defended my approach over Tim's.

I *am* disappointed that no one else has bothered to
"vote" for one approach over the other. The vote
still stands at 1-1 ....

I will remove the code or the attribution at Tim's request.
(I hunted to find parts of my e-mail exchange with Tim which
was at a Yahoo e-mail I use no more. My present e-mail
is jamesdowallen at Gmail.)

The code on the webpage shouldn't be referred to as "Tim's code",
since it's not what I wrote. As long as it's clear that the
writing there isn't mine and that the comments I did make were
written for another context, it should be okay. Something like,
"In a discussion in comp.lang.c, Tim Rentsch suggested [link to
original article] code somewhat along the following lines."
If these kinds of changes are made leaving the other text
intact shouldn't be a problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top