use of do{...}while(0)

S

sathyashrayan

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:
sathyashrayan AT gmail DOT com
 
J

Joona I Palaste

sathyashrayan said:
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?

It's a clever way to make a multi-statement macro appear to work like a
function.
Consider:

#define DO_MAGIC_STUFF(x) {foo(x); bar(x);}
if (willDoMagic)
DO_MAGIC_STUFF(quux);
else
printf("Won't do magic stuff!\n");

This won't compile (exercise: why?). However, change the definition
to:

#define DO_MAGIC_STUFF(x) do {foo(x); bar(x);} while (0)

and it will compile (exercise: why?).
 
L

Larry__Weiss

sathyashrayan said:
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?

The answer text at 10.4 is probably about as good an explanation as is needed
if you understand the context. It's about writing a C language macro that
expands effectively into several standalone C statements.

Just mentally think about what the do{...}while(0) wrapper is doing and you'll
see how the "trick" works.

- Larry Weiss
 
L

Lawrence Kirby

It's a clever way to make a multi-statement macro appear to work like a
function.

Not a function as such, a single statement requiring a ; at the end to
complete it.
Consider:

#define DO_MAGIC_STUFF(x) {foo(x); bar(x);} if (willDoMagic)
DO_MAGIC_STUFF(quux);

You're right though that it is very likely to appear in a function-like
macro.
else
printf("Won't do magic stuff!\n");

This won't compile (exercise: why?). However, change the definition to:

#define DO_MAGIC_STUFF(x) do {foo(x); bar(x);} while (0)

and it will compile (exercise: why?).

And there's a big clue in my reply. :)

Lawrence
 
S

sathyashrayan

Joona said:
It's a clever way to make a multi-statement macro appear to work like a
function.
Consider:

#define DO_MAGIC_STUFF(x) {foo(x); bar(x);}
if (willDoMagic)
DO_MAGIC_STUFF(quux);
else
printf("Won't do magic stuff!\n");

This won't compile (exercise: why?). However, change the definition
to:

#define DO_MAGIC_STUFF(x) do {foo(x); bar(x);} while (0)

and it will compile (exercise: why?).

I have got zero marks in both of the exercise!?

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
S

sathyashrayan

Joona said:
It's a clever way to make a multi-statement macro appear to work like a
function.
Consider:

#define DO_MAGIC_STUFF(x) {foo(x); bar(x);}
if (willDoMagic)
DO_MAGIC_STUFF(quux);
else
printf("Won't do magic stuff!\n");

This won't compile (exercise: why?). However, change the definition
to:

#define DO_MAGIC_STUFF(x) do {foo(x); bar(x);} while (0)

and it will compile (exercise: why?).

I have got zero marks in both of the exercises!?

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
J

Joona I Palaste

I have got zero marks in both of the exercises!?

Let's preprocess the code by hand. The first version will expand to:

if (willDoMagic)
{foo(quux); bar(quux);};
else
printf("Won't do magic stuff!\n");

The second will expand to:

if (willDoMagic)
do {foo(quux); bar(quux);} while (0);
else
printf("Won't do magic stuff!\n");

Now take a good look at these, particularly the "if" branch in the first
example.
 
J

Jonathan Burd

sathyashrayan said:
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?

#define TEST(_x) \
{ \
/* do something
* with _x
*/ \
}

works too.

Regards,
Jonathan.
 
M

Michael Mair

Jonathan said:
#define TEST(_x) \
{ \
/* do something
* with _x
*/ \
}

works too.

In most but not all cases.
Just have a look at FAQ 10.4 or the other posts in this thread.

-Michael
 
V

Vimal Aravindashan

Michael said:
In most but not all cases.
Just have a look at FAQ 10.4 or the other posts in this thread.

-Michael

It will work fine as long as you don't put a semi-colon while calling
the macro, i.e. TEST(abc) will work but TEST(abc); won't. Macros are
expanded before checking for syntax errors, so TEST(abc) will not throw
up any syntax errors, but it will appear confusing to someone reading
the code.

Vimal.
 
S

sathyashrayan

Joona said:
Let's preprocess the code by hand. The first version will expand to:

if (willDoMagic)
{foo(quux); bar(quux);};
else
printf("Won't do magic stuff!\n");
The functions will called till willDoMAgic becomes false.
The second will expand to:

if (willDoMagic)
do {foo(quux); bar(quux);} while (0);
else
printf("Won't do magic stuff!\n");
Both functions are called , as like above, only once since the value
in the while is zero.
Now take a good look at these, particularly the "if" branch in the first
example.

But I don't find any difference in the two versions of macros since
both function is called only once.

BTW, TELL THE ANSWER PLEASE.........

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
Z

Zilla

Joona said:
sathyashrayan <[email protected]> scribbled the following:


Let's preprocess the code by hand. The first version will expand to:

if (willDoMagic)
{foo(quux); bar(quux);};
else
printf("Won't do magic stuff!\n");

The second will expand to:

if (willDoMagic)
do {foo(quux); bar(quux);} while (0);
else
printf("Won't do magic stuff!\n");

Now take a good look at these, particularly the "if" branch in the first
example.
I cannot find any difference in branch "if", I want to get a answer,
too.
Thank you.
 
C

CBFalconer

sathyashrayan said:
Joona I Palaste wrote:
.... snip ...
The functions will called till willDoMAgic becomes false.

Both functions are called , as like above, only once since the value
in the while is zero.


But I don't find any difference in the two versions of macros since
both function is called only once.

BTW, TELL THE ANSWER PLEASE.........

He did. It's right in front of your nose.
 
J

Jonathan Burd

Zilla said:
Joona I Palaste wrote:

I cannot find any difference in branch "if", I want to get a answer,
too.
Thank you.

<snip>

What do you think this does?
----------------------------

if (condition)
{
/* do something here */
}; /* notice the semicolon. */
else
{
/* do something else here. */
}

Now try this:
-------------

if (condition)
do
{
/* do something here */
} while(0);
else
{
/* do something else here. */
}

Regards,
Jonathan.
 
J

Jonathan Burd

Joona said:
No it doesn't. I just explained why.

I figured why I didn't come across the problem you have shown before.
I prefer using braces for if-else ladders even if they have only
one statement each. Anyhow, thanks for pointing out.

Regards,
Jonathan.
 
J

junky_fellow

Joona said:
sathyashrayan <[email protected]> scribbled the following:

It's a clever way to make a multi-statement macro appear to work like a
function.
Consider:

#define DO_MAGIC_STUFF(x) {foo(x); bar(x);}
if (willDoMagic)
DO_MAGIC_STUFF(quux);
else
printf("Won't do magic stuff!\n");

This won't compile (exercise: why?).

I think if you remove the semicolon after DO_AMGIC_STUFF(quux)
it will both compile and executes the desired way.
Then why to use
do { } while(0);
Note: it is also costlier as there is an extra test at the end of loop.
Is there any case where we can't go without using do { } while(0);
 
J

Joona I Palaste

(e-mail address removed) scribbled the following:
I think if you remove the semicolon after DO_AMGIC_STUFF(quux)
it will both compile and executes the desired way.
Then why to use
do { } while(0);
Note: it is also costlier as there is an extra test at the end of loop.
Is there any case where we can't go without using do { } while(0);

I just explained above why to use the semicolon. It's to make the macro
appear like a function.
You don't call functions like this:
do_magic_stuff(quux)
You call them like this:
do_magic_stuff(quux);
Why should the syntax be any different for macros? If you ever decide to
change the macro to a function, or the function to a macro, you would
have to change the syntax in every place it is invoked. Plus it lessens
the consistency, making the code harder to read.
The point is, of course it's possible to avoid using do { } while(0) by
not using the semicolon at the end of the invocation, but it's easier
this way.
And it's not necessarily costlier to have an extra test at the end of
the loop. A clever compiler might deduce that the test is never going to
succeed, and thus omit it entirely, causing no performance loss
whatsoever.
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top