[comp.lang.c] Multi-statement macros

sullivan@aqdata.uucp (Michael T. Sullivan) (02/09/90)

One of the packages we use has some macros for returning values
from a function.  You call these macros when you want to return
instead of calling return.  An example is:

#define	new_return(n)	s1; s2; return (something)

This just wouldn't do so I put braces around the statements.  Recent
discussion here led me to change this macro to:

#define	BEGIN_BLOCK	do {
#define	END_BLOCK	} while (0)
#define	new_return(n)	BEGIN_BLOCK s1; s2; return (something); END_BLOCK

Problem with this particular macro is that because it has a return in it,
we would get a "statement not reached" warning from the compiler.  I then
changed BEGIN_ and END_BLOCK to:

#define	BEGIN_BLOCK	do { if (1) {
#define	END_BLOCK	} } while (0)

This seems to make everything happy.  My question is, will this make other
machines happy?  We are using a 3B2/400 SVR3 and it didn't even complain
when just braces were used (resulting in "};").  Does this shut everything
up on YOUR machine?

P.S. That BEGIN_BLOCK/END_BLOCK stuff really DOES come in handy.
-- 
Michael Sullivan          uunet!jarthur!aqdata!sullivan
aQdata, Inc.              sullivan@aqdata.uucp
San Dimas, CA             +1 714 599 9992

frankw@hpcvra.CV.HP.COM (Frank Wales) (02/10/90)

In some article, sullivan@aqdata.uucp (Michael T. Sullivan) wrote:
[an article about writing macros which do things that are forbidden
 in expressions, like using return, which concluded with...]

>I then changed BEGIN_ and END_BLOCK to:

>#define	BEGIN_BLOCK	do { if (1) {
>#define	END_BLOCK	} } while (0)

>This seems to make everything happy.  My question is, will this make other
>machines happy?  We are using a 3B2/400 SVR3 and it didn't even complain
>when just braces were used (resulting in "};").  Does this shut everything
>up on YOUR machine?

I have used the do { ... } while(0) trick on many occasions to write macros
which declare temporary variables.  This produces a warning of the form
"constant in conditional context" when compiled on an HP9000 PA machine
(s600 or s800), which I live with (a compiler directive to get rid of
it on a case-by-case basis would be useful, but I'm not that bothered;
I would definitely not want an option which just lost all these warnings).
--
Frank Wales, Guest of HP Corvallis, [frank@zen.co.uk||frankw@hpcvdq.cv.hp.com]
Zengrange Ltd., Greenfield Rd., LEEDS, England, LS9 8DB. (+44) 532 489048 x217

martin@mwtech.UUCP (Martin Weitzel) (02/21/90)

In article <17000001@hpcvra.CV.HP.COM> frankw@hpcvra.CV.HP.COM (Frank Wales) writes:
} In some article, sullivan@aqdata.uucp (Michael T. Sullivan) wrote:
} [an article about writing macros which do things that are forbidden
}  in expressions, like using return, which concluded with...]
} 
} >I then changed BEGIN_ and END_BLOCK to:
} 
} >#define	BEGIN_BLOCK	do { if (1) {
} >#define	END_BLOCK	} } while (0)
} 
} >This seems to make everything happy.  My question is, will this make other
} >machines happy?  We are using a 3B2/400 SVR3 and it didn't even complain
} >when just braces were used (resulting in "};").  Does this shut everything
} >up on YOUR machine?
} 
} I have used the do { ... } while(0) trick on many occasions to write macros
} which declare temporary variables.  This produces a warning of the form
} "constant in conditional context" when compiled on an HP9000 PA machine
} (s600 or s800), which I live with (a compiler directive to get rid of
} it on a case-by-case basis would be useful, but I'm not that bothered;
} I would definitely not want an option which just lost all these warnings).
} --
} Frank Wales, Guest of HP Corvallis, [frank@zen.co.uk||frankw@hpcvdq.cv.hp.com]
} Zengrange Ltd., Greenfield Rd., LEEDS, England, LS9 8DB. (+44) 532 489048 x217

Compiler writers, here you have another argument for separating
'cc'-ing and 'lint'-ing some source. Then it would be easy to put
an #ifdef-ed wrapper around those bogus but sometimes necessary
stuff, which makes such macros look like functions while the source is
'lint'-ed.

To Frank: Here you have my hint what to do (esp. if you use make
for compilations): Disable *all* warnings when you do the 'real'
compilation but have some additional target. In this case you may
use lint or let your compiler issue all warnings. If you use lint,
the macro 'lint' will automatically be defined, otherwise you must
call your compiler simply with "-Dlint". Then let your multi-statement
macros appears as if they were functions, depending on #ifdef lint.
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83