l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
October 20: Web Application Hacking: How to Make and Break Security on the Web
Next Installfest:
TBD
Latest News:
Oct. 10: LUGOD Installfests coming again soon
Page last updated:
2007 Jan 19 12:20

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] Nifty macro expansion bug
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] Nifty macro expansion bug



On Thu, Jan 18, 2007 at 05:27:20PM -0800, Gabriel G. Rosa wrote:
> On Thu, Jan 18, 2007 at 04:14:22PM -0800, Bill Kendrick wrote:
> > 
> > So at work, a coworker noticed an issue with the following code:
> > 
> >   for (i = 0; i < n; i++)
> >     myFREE(foo[i]);
> > 
> > which went away when he wrapped it in braces:
> > 
> >   for (i = 0; i < n; i++)
> >   {
> >     myFREE(foo[i]);
> >   }
> > 
> > Figured maybe it was a weird compiler bug.  Being author of the myFREE()
> > code -- which happens to be a macro -- I realized immediately what I did
> > wrong.  (And continue to be annoyed with C syntax ;) )
> > 
> > See, myFREE() is actually a macro that looks like this:
> > 
> >   #define myFREE(x) if ((x) != NULL) FREE(x); x = NULL;
> > 
> > Two statements... hence the need for {} around the call to the macro.
> > (Or, more sensibly, including {}s around what the macro expands to.)
> > 
> > That was a neat catch. :)
> > 
> 
> I believe the standard way of doing macros in the linux kernel is to use a
> bogus do-while, ie:
> 
> #define CRASHMACHINE() do { laughtAtUser(); crashMachine(); } while(0);
> 
> that way, any expansion like:
> 
> if(completelyRandomCondition())
> 	CRASHMACHINE();
> 	
> doesn't end up being expanded as:
> 
> if(completelyRandomCondition())
> 	laughAtUser(); crashMachine();
> 
> 	               ^ oops, outside of if scope
> 
> but as
> 
> if(completelyRandomCondition())
> 	do ( laughAtUser(); crashMachine(); } while(0);
> 
> which will execute once and only once.
> 
> I saw a good post on this once, but I can't really remember where.
> 

Oh, and right after I hit send the real reason for the do-while instead
of just {} comes to me, as does where I read it:

http://kernelnewbies.org/FAQ/DoWhile0

-Gabe
_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech



LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Sunset Systems
Who graciously hosts our website & mailing lists!