Topic: Is do ... while(0) obsolete?


Author: wallace@netcom.com (David E. Wallace)
Date: 1996/08/14
Raw View
[Moderator's note: this article is crossposted to comp.std.c++ and
comp.std.c, and followups have been directed by default to comp.std.c.
mha]

A certain company has contracted with a consultant (both of which
I will leave anonymous) to upgrade a bunch of not-quite-ANSI C code
to the ANSI standard.  This is primarily for staffing reasons, as
all of Company's C programmers are busy with other projects.
Some of this code contains multi-line macro definitions that are
wrapped in a do ... while(0), as recommended in the C FAQ, question 10.4:

#define MACRO(arg1, arg2) do { \
 blah1; \
 blah2; \
 /* ... */ \
 } while(0)
...
MACRO(x, y);
...
MACRO(z, y);
...

etc.

Consultant has changed these macros so they read like this:

#define MACRO(arg1, arg2) \
int macro_do_once = 0;\
do { \
 blah1; \
 blah2; \
 /* ... */ \
 } while(macro_do_once)
...
{MACRO(x, y);}
...
{MACRO(z, y);}
...

which sort of defeats the purpose of wrapping the code
in the do ... while to begin with.  When queryed about this
practice, Consultant has claimed that the "latest version" of
the standard prohibits the do ... while(0) construct.  Company's
staff considers this claim to be dubious, but none of them has a
copy of the "latest version" of the standard (with all the latest
corrections, interpretations, etc.) to quote back at Consultant.

My question, therefore, is: is there anything in either the current standards
or working drafts of future versions of either the C or C++ standards
that would depreciate, much less prohibit, this widespread practice?
If you have special expertise to answer this question (member of one
of the committees, etc.), I would appreciate it if you could include
a brief summary of such expertise in your reply.

P.S.: If it matters, some of the macros are actually single-statement
conditionals, such as:

#define MACRO1(w, x, y, z)\
do\
  if (condition(x, y, z))\
    w=func(y);\
  else\
    w=func(z);\
while (0)

which was converted to:

#define MACRO1(w, x, y, z)\
int do_macro_once = 0;\
do\
  if (condition(x, y, z))\
    w=func(y);\
  else\
    w=func(z);\
while (do_macro_once)

--
Dave Wallace  (wallace@netcom.com)
It is quite humbling to realize that the storage occupied by the longest
line from a typical Usenet posting is sufficient to provide a state space
so vast that all the computation power in the world can not conquer it.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]