473,544 Members | 550 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

do{..}while(0) macro substitutions

Yan
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
Nov 14 '05 #1
27 31825
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
Nov 14 '05 #2
Yan <ro*****@gmail. com> 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: bl*@cs.stanford .edu
web: http://benpfaff.org
Nov 14 '05 #3
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 "invocation s"

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
Nov 14 '05 #4
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?
Nov 14 '05 #5
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."

Nov 14 '05 #6

"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote in message
news:cr******** **@nntp1.jpl.na sa.gov...
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

Nov 14 '05 #7
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(doub le x) {
func1(x);
func2(x);
func3(x);
}
Nov 14 '05 #8
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.
Nov 14 '05 #9
"italy" <it****@gmail.c om> 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_Keit h) ks***@mib.org <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.
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
3212
by: Andrew Dalke | last post by:
Here's a proposed Q&A for the FAQ based on a couple recent threads. Appropriate comments appreciated X.Y: Why doesn't Python have macros like in Lisp or Scheme? Before answering that, a clarification on what 'macro' means. A Lisp macro is a way of modifying code when that code is first defined. It can rearrange the structure of the...
7
23530
by: Newbie_sw2003 | last post by:
Where should I use them? I am giving you my understandings. Please correct me if I am wrong: MACRO: e.g.:#define ref-name 99 The code is substituted by the MACRO ref-name. So no overhead. Execution is faster. Where will it be stotred?(Is it in bss/stack/?) FUNCTION:
36
14083
by: Martin | last post by:
Can anyone help with a quick query... I've seen the ASSERT macro defined as: #define ASSERT(f) \ do { \ if (!(f) && assertFailedOnLine (THIS_FILE, __LINE__)) \ FatalExit (0); \ } while (0) \
20
1695
by: sathyashrayan | last post by:
What is the use of the above do-while. Is it simply a style issue. Since the above same condition will applied with out a do-while(0); because the loop executes only once. I went through the faq section 10.4 but I am little understood. Any answers please? -- "combination is the heart of chess" A.Alekhine Mail to:
16
2228
by: vashwath | last post by:
Hi all, Below macro moves specified number of bytes from a specified index of source string to a specified index of destination string. #define STRMOV(src_str,src_ind,length,dst_str,dst_ind)\ do\ {\ int s,d;\ s = src_ind;\
8
2165
by: abhishek | last post by:
>>a,b=3,4 7 Now I want to evaluate y by substituting for the evaluated value of x. eval(y) will try to add "a+b" to 3 and return an error. I could do this, 10 but this becomes unwieldy if I have and so on, because the replacements have to be done in exactly the
5
3475
by: Bill | last post by:
This database has no forms. I am viewing an Access table in datasheet view. I'd like to execute a macro to execute a function (using "runcode"). In the function, I'll reading data from the record the cursor was on in the datasheet at the time I executed the macro. So, the questions are: 1) In the macro, how to I get my hands on the record...
9
321
by: Francois Grieu | last post by:
Consider this macro // check if x, assumed of type unsigned char, is in range #define ISVALID(x) ((x)>=0x20 && (x)<=0x7E) Of course, this can't be safely used as in if (ISVALID(*p++)) foo(); where p is a pointer ot unsigned char.
2
1442
by: RandDproject115 | last post by:
Is there anyway to edit the information in a textbox while the macro is running. I am trying to do this in Excel 2003 VB macros. Thanks for the help.
0
7365
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
1
7376
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
5909
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5297
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3415
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3409
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1841
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
988
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
661
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.