Thread View: net.lang.c
13 messages
13 total messages
Started by Dale Worley
Wed, 01 Oct 1986 20:16
Disappearing function call
Author: Dale Worley
Date: Wed, 01 Oct 1986 20:16
Date: Wed, 01 Oct 1986 20:16
53 lines
1706 bytes
1706 bytes
What I want to do is to write a function call of a variable number of arguments: debug(x, y, z, ...) that will generate no code when the symbol DEBUG is not defined, but generate a call of some function (say, debug_()) when it is. If debug() always had the same number of arguments, we could use #ifdef DEBUG #define debug(x, y, z) debug_(x, y, z) #else #define debug(x, y, z) /* null */ but macros aren't allowed to have a variable number of arguments. The best solutions I've heard so far are: 1) We write debug(x Z y Z z) using "Z" instead of ",". Using the definitions #ifdef DEBUG #define debug(x) debug_(x) #define Z , #else #define debug(x) /* null */ #endif works, since the "Z"s are turned into "," after the call of debug() is expanded. This is ugly because you have to write "Z" instead of ",". 2) We write debug(x, y, z)) Using the definitions #ifdef DEBUG #define debug (debug_ #else #define debug debug1( #define debug1(x) /* null */ This works when DEBUG is off by replacing the call to debug() to a call to debug1() with one argument, which is then ignored. This ugly because of the mismatched parentheses. Is there a good way to do this? Dale
Re: Disappearing function call
Author: Frank Whaley
Date: Thu, 02 Oct 1986 17:21
Date: Thu, 02 Oct 1986 17:21
48 lines
1770 bytes
1770 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes:
>What I want to do is to write a function call of a variable number of
>arguments:
> debug(x, y, z, ...)
>that will generate no code when the symbol DEBUG is not defined, but
>generate a call of some function (say, debug_()) when it is.
Numerous ugly examples deleted.
I had to do this just recently, and took advantage of the fact that my
compilers "optimize out" code like this:
if (0) function();
So assuming:
#ifdef DEBUG
#define _DEBUG 1
extern void _debug(char *,) /* debugging printf() */
#else
#define _DEBUG 0
#endif
#define debug if(_DEBUG)_debug
a statment like:
debug("%d:%d:%d\n", a, b, c);
becomes either:
if(1)_debug("%d:%d:%d\n", a, b, c);
or
if(0)_debug("%d:%d:%d\n", a, b, c); /* no code generated */
All of my compilers generate the strings anyway, so I used a set of external
strings (bracketed by #ifdef's) for all debugging messages. Some compilers
require an optimizer pass to eat the dead code.
--
Frank Whaley
Senior Engineer, Beyond Words
UUCP: hplabs!
ihnp4!ptsfa!
seismo!lll-crg!well!few
ARPA: well!few@lll-crg.ARPA
Water separates the people of the world;
wine unites them.
Re: Disappearing function call
Author: Hall
Date: Thu, 02 Oct 1986 17:44
Date: Thu, 02 Oct 1986 17:44
61 lines
3066 bytes
3066 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes: >What I want to do is to write a function call of a variable number of >arguments: > > debug(x, y, z, ...) > >that will generate no code when the symbol DEBUG is not defined, but >generate a call of some function (say, debug_()) when it is. If >debug() always had the same number of arguments, we could use > > #ifdef DEBUG > #define debug(x, y, z) debug_(x, y, z) > #else > #define debug(x, y, z) /* null */ > >but macros aren't allowed to have a variable number of arguments. How about this: #ifndef DEBUG #define debug #endif and writing in the code: debug(a,b,c) If DEBUG is turned on, nothing will happen to the debug statements, so a call to debug will be produced (as you would expect). If DEBUG isn't defined, the symbol "debug" will be pre-processed out of existance, so the compiler will see an expression like: (a,b,c) If the arguments don't produce any side effects, I believe that most decent compilers will not emit any code (or at least the optimizer should be able to detect a load of a useless register. If the debug function returns a value that is checked, when DEBUG is turned off, the value will be the last parameter, which will generate code, but I don't suppose that the debug routine actually returns a value. Simple expressions as arguments to the debug function should also produce no code if DEBUG is turned off, but it is possible that complex expressions could fool the compiler into generating code for parts of the expression then throwing the result away. One way that this could generate code is if the optimizer has to remove the useless loads and this is the last expression in the function (so that there isn't a return statement). If a value is loaded into the register that is used for the return value, the optimizer may think that that is the return value and thus it wouldn't think it was a useless load. If any of the arguments have side effects or involve function calls (with potential side effects there!), these will (and should) always be generated. However, I don't think that it is likely that you would want to be doing this sort of thing in a call to a debugging macro. Are there any problems with doing this? I suppose that some pre-processors could choke on the parenthesis after debug in the invocation, since debug is #defined as a parameter-less macro, but my pre-processor (SVR2) doesn't. Marcus Hall ..!ihnp4!ihlpl!marcus
Re: Disappearing function call
Author: Geoff Kimbrough
Date: Thu, 02 Oct 1986 19:37
Date: Thu, 02 Oct 1986 19:37
14 lines
1039 bytes
1039 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes:
>What I want to do is to write a function call of a variable number of
>arguments:
> debug(x, y, z, ...)
I've used this construction
#if DEBUG
#define debug(X) printf X /* note NO parentheses */
#else
#define debug(X)
#endif
and written
debug(( "stuff =%x blek = %d", var1,var2)) /* note double parentheses */
seems to work for me.
You're welcome.
Re: Disappearing function call
Author: kenny
Date: Fri, 03 Oct 1986 14:49
Date: Fri, 03 Oct 1986 14:49
46 lines
2103 bytes
2103 bytes
/* Written 12:44 pm Oct 2, 1986 by marcus@ihlpl.UUCP in uiucdcsb:net.lang.c */
>In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes:
>>What I want to do is to write a function call of a variable number of
>>arguments:
>>
>> debug(x, y, z, ...)
>>
>>that will generate no code when the symbol DEBUG is not defined,
[...]
>How about this:
>
>#ifndef DEBUG
>#define debug
>#endif
>
>and writing in the code:
>
> debug(a,b,c)
>
>If DEBUG is turned on, nothing will happen to the debug statements, so a
>call to debug will be produced (as you would expect). If DEBUG isn't
>defined, the symbol "debug" will be pre-processed out of existance, so
>the compiler will see an expression like:
>
> (a,b,c)
[...]
>Are there any problems with doing this? I suppose that some pre-processors
>could choke on the parenthesis after debug in the invocation, since debug
>is #defined as a parameter-less macro, but my pre-processor (SVR2) doesn't.
>
>Marcus Hall
/* End of text from uiucdcsb:net.lang.c */
If you invoke it in the code as
debug (a, b, c)
^ Note the space!
then no preprocessor should ever confuse it; macros with parameters are
recognized only if no space intervenes between the macro name and the
left parenthesis.
Kevin Kenny UUCP: {ihnp4,pur-ee,convex}!uiucdcs!kenny
University of Illinois at Urbana-Champaign CSNET: kenny@UIUC.CSNET
``Don't worry; I'm a New Yorker!'' ARPA: kenny@B.CS.UIUC.EDU (kenny@UIUC.ARPA)
Re: Disappearing function call
Author: John Plocher
Date: Fri, 03 Oct 1986 18:01
Date: Fri, 03 Oct 1986 18:01
25 lines
1288 bytes
1288 bytes
<f u cn rd ths, u hv no ln etr>
There were some debug routines posted in net.sources which use this format:
#ifdef DEBUG
# define TRACE printf
#else
# define TRACE
#endif
...
TRACE("The error '%s' is on line %d\n", errorname, lineno);
...
which expands into
printf(...) if DEBUG is defined,
and into
(...) if not. Note that (...) does NOT GENERATE CODE, but is rather
just an expression.
--
harvard-\ /- uwmacc!uwhsms!plocher (work)
John Plocher seismo-->!uwvax!<
topaz-/ \- puff!plocher (school)
civil flames (ie. ones which are WORTH reading) only, please!
"Never trust an idea you get sitting down" - Nietzche
Re: Disappearing function call
Author: Frank Adams
Date: Mon, 06 Oct 1986 00:17
Date: Mon, 06 Oct 1986 00:17
26 lines
1380 bytes
1380 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP writes: >What I want to do is to write a function call of a variable number of >arguments: > > debug(x, y, z, ...) > >that will generate no code when the symbol DEBUG is not defined, but >generate a call of some function (say, debug_()) when it is. Here's a possibility which is slightly ugly, as all the others are, but the ugliness is in a different place. Write: #ifdef DEBUG #define debug(a) debug_ a #else #define debug(a) #endif Now, write your debug statements with an extra pair of parentheses: debug((x, y, z, ...)); I'm not necessarily recommending this; it's just an idea. Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Multimate International 52 Oakland Ave North E. Hartford, CT 06108
Re: Disappearing function call
Author: Gregory Smith
Date: Mon, 06 Oct 1986 14:48
Date: Mon, 06 Oct 1986 14:48
23 lines
1195 bytes
1195 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes: >What I want to do is to write a function call of a variable number of >arguments: > > debug(x, y, z, ...) > >that will generate no code when the symbol DEBUG is not defined, but >generate a call of some function (say, debug_()) when it is. If You could write debug( ( x,y,z ) ); In the code, and #ifdef DEBUG # define debug(list) _debug list #else # define debug(list) #endif -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg
Re: Disappearing function call
Author: John Woods, Software
Date: Tue, 07 Oct 1986 19:43
Date: Tue, 07 Oct 1986 19:43
28 lines
1297 bytes
1297 bytes
> What I want to do is to write a function call of a variable number of
> arguments:
> debug(x, y, z, ...)
> that will generate no code when the symbol DEBUG is not defined, but
> generate a call of some function (say, debug_()) when it is.
Try:
#ifdef DEBUG
#define debug(x) x
#else
#define debug(x)
#endif
debug( puts("Shut 'er down, Scotty, she's sucking mud again."); )
The extra layer of indirection may feel irritating, but it also allows
debug( if (op == NULL) exit(puts("RATS RATS RATS [#566, para. 1]")); )
It's quick, it's easy, it works.
--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc@MIT-XX.ARPA
"Don't give me this intelligent life crap,
just find me a planet I can blow up."
Re: Disappearing function call
Author: Guido van Rossum
Date: Sat, 11 Oct 1986 12:30
Date: Sat, 11 Oct 1986 12:30
25 lines
1227 bytes
1227 bytes
In article <357@cullvax.UUCP> drw@cullvax.UUCP (Dale Worley) writes: >What I want to do is to write a function call of a variable number of >arguments: > > debug(x, y, z, ...) > >that will generate no code when the symbol DEBUG is not defined, but >generate a call of some function (say, debug_()) when it is. If >Is there a good way to do this? If you are willing to write extra parentheses but want them to match, write this: #ifdef DEBUG #define debug(x) debug_ x #else #define debug(x) /* empty */ #endif and call as follows: debug((x, y, z, ...)); -- Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>
Re: Disappearing function call
Author: mcg
Date: Sun, 12 Oct 1986 22:22
Date: Sun, 12 Oct 1986 22:22
29 lines
1430 bytes
1430 bytes
You guys are all thinking too hard. Even the venerable Chris Torek has proposed a solution more complex than needed. On any compiler likely to be used for production code, the optimizer will generate no code whatsoever for the following fragment: #define DEBUG 0 /* set to 1 to turn debugging on */ ... if (DEBUG) debug(...); Similarly, in the case of '#define DEBUG 1', the unneccesary test will be elided. In the idiom of the original posting, the example is: #define debug if(DEBUG) debug debug(x,y,z); Though care must be taken in using this form in un-braced if statements that have else clauses. The preprocessor solutions have the intoxicating air of complexity about them, but, in my experience, this solution proves easiest and most effective. Why look for trouble? Trouble will find you. S. McGeady
Re: Disappearing function call
Author: Lawrence W. McVoy
Date: Mon, 27 Oct 1986 06:38
Date: Mon, 27 Oct 1986 06:38
37 lines
1396 bytes
1396 bytes
In article <162@omepd> mcg@omepd.UUCP (Steven McGeady) writes:
>
>You guys are all thinking too hard.
>
> #define DEBUG 0 /* set to 1 to turn debugging on */
> ...
> if (DEBUG) debug(...);
>
>Similarly, in the case of '#define DEBUG 1', the unneccesary test will
>be elided.
>
>In the idiom of the original posting, the example is:
>
> #define debug if(DEBUG) debug
>
> debug(x,y,z);
I came into this late, so you might already know this, but try this on for
size anyway:
# ifdef DEBUG
# define debug(x) fprintf x
# else
# define debug(x)
# endif
.....
debug((stderr, "Control string", arg1, arg2, ... argn));
Cute, isn't it? I stole it out of the src to enscript (adobe something or
other).
--
Larry McVoy mcvoy@rsch.wisc.edu,
{seismo, topaz, harvard, ihnp4, etc}!uwvax!mcvoy
"They're coming soon! Quad-stated guru-gates!"
Re: Disappearing function call
Author: andy
Date: Tue, 28 Oct 1986 08:11
Date: Tue, 28 Oct 1986 08:11
31 lines
1636 bytes
1636 bytes
#define DEBUG 1 /* or 0 as appropriate */
#define debug if( DEBUG ) fprintf
(Replace fprintf with the appropriate function.)
Then you can write:
debug( stderr, "wrong args %d, %s, %p\n", d, s, p ); /* %p is bogus */
Either your compiler eliminates dead code or it doesn't.
If it doesn't, other dead code and missed opportunities to generate
good code will swamp the overhead of checking if 0 is still 0 and
skipping the fprintf. If it does, the fprintf (and its args) will be
removed.
-andy
ps - Yes, I know my debug will pick up a following "else". I use "extra"
{}'s and debug( <args> ) shouldn't be followed by an "else" anyway; I'll
document that feature and let it slide. It is difficult to handle all
possible constraints with something as limited as cpp; "debug( (<args>) )"
grates on me.
I'd rather write "if( DEBUG ) <code>" directly than "debug( <args> )"
because it doesn't restrict <code>.
--
Andy Freeman
UUCP: ...!decwrl!shasta!andy forwards to
ARPA: andy@sushi.stanford.edu
(415) 329-1718/723-3088 home/cubicle
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads