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!)
···
–
Jamis Buck
jgb3@email.byu.edu
ruby -h | ruby -e ‘a=[];readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a << r.compact.first };puts “\n>#{a.join(%q/ /)}<\n\n”’
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
···
On Dec 29, 2003, at 15:54, Jamis Buck wrote:
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?
Hi,
[…] 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
···
From: “Jamis Buck” jgb3@email.byu.edu
Dave Thomas wrote:
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. 
···
–
Jamis Buck
jgb3@email.byu.edu
ruby -h | ruby -e ‘a=;readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a << r.compact.first };puts “\n>#{a.join(%q/ /)}<\n\n”’
Bill Kelly wrote:
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.
···
–
Jamis Buck
jgb3@email.byu.edu
ruby -h | ruby -e ‘a=;readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a << r.compact.first };puts “\n>#{a.join(%q/ /)}<\n\n”’
See above… Compile it in your head with just the braces…
Dave
···
On Dec 29, 2003, at 16:22, Jamis Buck wrote:
Dave Thomas wrote:
if (something)
MACRO;
else
puts(“hello”);
With just {}'s around the macro, the second case wouldn’t compile
(because of the semicolon).
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:
It’s good style in general. Consider
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
···
–
::: name: Nikolai Weibull :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA :: loc atm: Gothenburg, Sweden :::
::: page: www.pcppopper.org :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux[“\021%six\012\0”],(linux)[“have”]+“fun”-97);}