Question about Ruby implementation

J

Jamis Buck

I've been poking around the Ruby internals, trying to understand the
black magic that makes the whole thing run. :) I think I finally
understand the garbage collection stuff (and how it determines the roots
from the stack and registers), but I have a question now about some of
the macros I've seen: why do some macros wrap their contents in a "do {
... } while(0)"? Is this preferable to simply wrapping them in curly
braces ("{...}")? Is it simply a matter of matz's programming style, or
is there some subtler issue in effect here?

A few macros that do this (for curious persons to reference) are
JUMP_TAG (in eval.c) and RUBY_CRITICAL (in rubysig.h), though there are
several others.

Thanks! (And if there is a more appropriate list for posting questions
regarding the implementation of Ruby, please direct me there. Thanks
again!)
 
D

Dave Thomas

why do some macros wrap their contents in a "do { ... } while(0)"?
Is this preferable to simply wrapping them in curly braces ("{...}")?
Is it simply a matter of matz's programming style, or is there some
subtler issue in effect here?

It's good style in general. Consider

if (something)
MACRO;

and

if (something)
MACRO;
else
puts("hello");

With just {}'s around the macro, the second case wouldn't compile
(because of the semicolon).


Cheers


Dave
 
B

Bill Kelly

Hi,

From: "Jamis Buck said:
[...] I have a question now about some of
the macros I've seen: why do some macros wrap their contents in a "do {
... } while(0)"? Is this preferable to simply wrapping them in curly
braces ("{...}")? Is it simply a matter of matz's programming style, or
is there some subtler issue in effect here?

It's a 'C' language idiom. It makes a terminating semi-colon
a required part of the syntax, which helps avoid mistakes
with the one-liner form of (for instance) if/else statements,
and such.

#define THING1 {blah()}
#define THING2 do{blah()}while(0)

if (rand() & 1)
THING1();
else
THING2();

...note problem with THING1() usage, given the extraneous
semi-colon...


HTH,

Regards,

Bill
 
J

Jamis Buck

Dave said:
It's good style in general. Consider

if (something)
MACRO;

and

if (something)
MACRO;
else
puts("hello");

With just {}'s around the macro, the second case wouldn't compile
(because of the semicolon).


Cheers


Dave

Yah, I understand that, I think. But why have MACRO wrap its contents
in a "do{...}while(0)", instead of just "{...}"? In other words, is
there a compelling reason to do this:

#define MACRO(x) \
do { \
x \
} while(0)

instead of this:

#define MACRO(x) \
{ \
x \
}

I'm just curious -- if it just comes down to a personal preference
thing, that's fine. But if there is a good reason for doing one over
the other, I'd like to know. Thanks. :)
 
J

Jamis Buck

Bill said:
It's a 'C' language idiom. It makes a terminating semi-colon
a required part of the syntax, which helps avoid mistakes
with the one-liner form of (for instance) if/else statements,
and such.

#define THING1 {blah()}
#define THING2 do{blah()}while(0)

if (rand() & 1)
THING1();
else
THING2();

...note problem with THING1() usage, given the extraneous
semi-colon...

Perfect -- that's what I was looking for. That makes perfect sense.
Thanks!

Reading through this stuff is humbling... I once considered myself a
pretty good C programmer, but puzzling out some of the stuff the
interpreter is doing has been very educational.
 
D

Dave Thomas

ah, I understand that, I think. But why have MACRO wrap its contents
in a "do{...}while(0)", instead of just "{...}"? In other words, is
there a compelling reason to do this:

See above... Compile it in your head with just the braces...


Dave
 
N

Nikolai Weibull

* Jamis Buck said:
Yah, I understand that, I think. But why have MACRO wrap its contents
in a "do{...}while(0)", instead of just "{...}"? In other words, is
there a compelling reason to do this:

#define MACRO(x) \
do { \
x \
} while(0)

instead of this:

#define MACRO(x) \
{ \
x \
}
no one prefers this - some compilers actually generate code for the
do-while (which is incredible...), the reason is that braces used in the
second way isn't standard in C89 (if i'm not mistaken) or at least not
supported by all compilers. A way would be to use another macro that
would encapsulate this stuff, as GLib does provide.
nikolai
 

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,772
Messages
2,569,593
Members
45,112
Latest member
VinayKumar Nevatia
Top