Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > do{..}while(0) macro substitutions

Reply
Thread Tools

do{..}while(0) macro substitutions

 
 
Yan
Guest
Posts: n/a
 
      12-30-2004
A lot of times when reading open software, i come across macros that are
defined as follows:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0);

now, of course this will work but how is this any better than:

#define CALL_FUNCS(x) \
{ \
func1(x); \
func2(x); \
func3(x); \
}

i can't see how the compiler can optimize (a) any better than (b) or in
any case can (b) break what (a) won't. Any input will be appreciated.

tia
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      12-30-2004
Yan <(E-Mail Removed)> writes:

> A lot of times when reading open software, i come across macros that
> are defined as follows:
>
> #define CALL_FUNCS(x) \
> do { \
> func1(x); \
> func2(x); \
> func3(x); \
> } while (0);


Read the FAQ.
--
Ben Pfaff
email: http://www.velocityreviews.com/forums/(E-Mail Removed)
web: http://benpfaff.org
 
Reply With Quote
 
 
 
 
Alexandre
Guest
Posts: n/a
 
      12-30-2004
Hello,

Yan a écrit :
> A lot of times when reading open software, i come across macros that are
> defined as follows:
>
> #define CALL_FUNCS(x) \
> do { \
> func1(x); \
> func2(x); \
> func3(x); \
> } while (0);

are you sure there is ";" at the end ?
because I thought the reason why you use "do { } while(0)" is this ";" !
you don't have to put it there, and I explain why after...

>
> now, of course this will work but how is this any better than:
>
> #define CALL_FUNCS(x) \
> { \
> func1(x); \
> func2(x); \
> func3(x); \
> }
>
> i can't see how the compiler can optimize (a) any better than (b) or in
> any case can (b) break what (a) won't. Any input will be appreciated.

you should see where it's used in the code, and then you will understand !
in the code you will find this :

....
CALL_FUNCS(12); /* becareful of this ";" */
....

so the preprocessor will replace CALL_FUNCS(12) by :
(a)
....
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0); /* <- this ";" will end do { } while(0) in good way */
....

(b)
....
{ \
func1(12); \
func2(12); \
func3(12); \
}; /* <- too much ";" */
....

Maybe there is another reason, but I'm sure I read this explanation
somewhere (maybe here).

Alexandre
--
"That's what they should teach us here", he (Harry Potter) thought, ...,
"how's girls' brains work ... it'd be more useful than Divination, anyway
...."

Harry Potter and the Order of the Phoenix
J.K. Rowling
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      12-30-2004
Yan wrote:
> A lot of times when reading open software, i come across macros that are
> defined as follows:
>
> #define CALL_FUNCS(x) \
> do { \
> func1(x); \
> func2(x); \
> func3(x); \
> } while (0);


> now, of course this will work but how is this any better than:
>
> #define CALL_FUNCS(x) \
> { \
> func1(x); \
> func2(x); \
> func3(x); \
> }
>
> i can't see how the compiler can optimize (a) any better than (b) or in
> any case can (b) break what (a) won't. Any input will be appreciated.


It is not about optimization.

The whole idea of using 'do/while' version is to make a macro which will
expand into a regular statement, not into a compound statement. This is
done in order to make the use of function-style macros uniform with the
use of ordinary functions in all contexts.

Consider the following code sketch

if (<condition>)
foo(a);
else
bar(a);

where 'foo' and 'bar' are ordinary functions. Now imagine that you'd
like to replace function 'foo' with a macro of the above nature

if (<condition>)
CALL_FUNCS(a);
else
bar(a);

Now, if your macro is defined in accordance with the second approach
(just '{' and '}') the code will no longer compile, because the 'true'
branch of 'i' is now represented by a compound statement. And when you
put a ';' after this compound statement, you finished the whole 'if'
statement, thus orphaning the 'else' branch (hence the compilation error).

One way to correct this problem is to remember not to put ';' after
macro "invocations"

if (<condition>)
CALL_FUNCS(a)
else
bar(a);

This will compile and work as expected, but this is not uniform. The
more elegant solution is to make sure that macro expand into a regular
statement, not into a compound one. One way to achieve that is to define
the macro as follows

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)

Now this code

if (<condition>)
CALL_FUNCS(a);
else
bar(a);

will compile without any problems.

However, note the small but important difference between my definition
of 'CALL_FUNCS' and the first version in your message. I didn't put a
';' after '} while (0)'. Putting a ';' at the end of that definition
would immediately defeat the entire point of using 'do/while' and make
that macro pretty much equivalent to the compound-statement version.

I don't know why the author of the code you quoted in your original
message put this ';' after 'while (0)'. In this form both variants are
equivalent. The whole idea behind using 'do/while' version is not to
include this final ';' into the macro (for the reasons that I explained
above).

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
E. Robert Tisdale
Guest
Posts: n/a
 
      12-30-2004
Ben Pfaff wrote:

> Yan writes:
>
>>A lot of times when reading open software,
>>I come across macros that are defined as follows:
>>
>>#define CALL_FUNCS(x) \
>>do { \
>> func1(x); \
>> func2(x); \
>> func3(x); \
>>} while (0);

>
> Read the FAQ.


Could you please cite and quote the FAQ
that is relevant to this question?
 
Reply With Quote
 
italy
Guest
Posts: n/a
 
      12-31-2004
It seems like this is an annoyance, so I wouldn't use any approach
mentioned above. If you really feel the conceit to do this, then
perhaps a function would be a better approach, even though it may
create overhead in some cases.
Good question.

-Adam Roan
"Just plain neat."

 
Reply With Quote
 
Dan P.
Guest
Posts: n/a
 
      12-31-2004

"E. Robert Tisdale" <(E-Mail Removed)> wrote in message
news:cr24cs$hto$(E-Mail Removed)...
> Ben Pfaff wrote:
>
>> Yan writes:
>>
>>>A lot of times when reading open software,
>>>I come across macros that are defined as follows:
>>>
>>>#define CALL_FUNCS(x) \
>>>do { \
>>> func1(x); \
>>> func2(x); \
>>> func3(x); \
>>>} while (0);

>>
>> Read the FAQ.

>
> Could you please cite and quote the FAQ
> that is relevant to this question?



I used Google

http://www.google.com/

to search for

"comp.lang.c faq multi-statement"

and the 1st link showed the FAQ # to be 10.4

http://www.eskimo.com/~scs/C-faq/q10.4.html



 
Reply With Quote
 
E. Robert Tisdale
Guest
Posts: n/a
 
      12-31-2004
Yan wrote:

> A lot of times when reading open software,
> I come across macros that are defined as follows:
>
> #define CALL_FUNCS(x) \
> do { \
> func1(x); \
> func2(x); \
> func3(x); \
> } while (0);


This practice is obsolete and should be discouraged.
Write inline function definitions instead:

inline static
void CALL_FUNCS(double x) {
func1(x);
func2(x);
func3(x);
}
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      12-31-2004
Yan wrote:
> A lot of times when reading open software, i come across macros that are
> defined as follows:
>
> #define CALL_FUNCS(x) \
> do { \
> func1(x); \
> func2(x); \
> func3(x); \
> } while (0);
>
> now, of course this will work but how is this any better than:
>
> #define CALL_FUNCS(x) \
> { \
> func1(x); \
> func2(x); \
> func3(x); \
> }
>
> i can't see how the compiler can optimize (a) any better than (b) or in
> any case can (b) break what (a) won't. Any input will be appreciated.


Try things like:

if (cond)
CALL_FUNCS(a);
else
CALL_FUNCS(b);

and see how far you get.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      12-31-2004
"italy" <(E-Mail Removed)> writes:
> It seems like this is an annoyance, so I wouldn't use any approach
> mentioned above. If you really feel the conceit to do this, then
> perhaps a function would be a better approach, even though it may
> create overhead in some cases.


It's a common C idiom that all C programmers should be familiar with.
If you find it annoying -- well, it's not the worst annoyance in the
language.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Macro substitutions James S. Singleton C Programming 7 01-05-2006 01:03 AM
using templates as substitutions for #ifdef Chris Goller C++ 4 03-09-2005 12:17 AM
Backslash substitutions Vivien Mallet Python 1 09-29-2004 07:24 PM
Ant problem with property substitutions. RJGraham Java 6 06-28-2004 03:49 AM
Tkinter: spinbox command and percent substitutions Tony Eva Python 1 11-09-2003 02:25 PM



Advertisments