🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

13 total messages Started by Dale Worley Wed, 01 Oct 1986 20:16
Disappearing function call
#9452
Author: Dale Worley
Date: Wed, 01 Oct 1986 20:16
53 lines
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
#9461
Author: Frank Whaley
Date: Thu, 02 Oct 1986 17:21
48 lines
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
#9464
Author: Hall
Date: Thu, 02 Oct 1986 17:44
61 lines
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
#9472
Author: Geoff Kimbrough
Date: Thu, 02 Oct 1986 19:37
14 lines
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
#9486
Author: kenny
Date: Fri, 03 Oct 1986 14:49
46 lines
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
#9475
Author: John Plocher
Date: Fri, 03 Oct 1986 18:01
25 lines
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
#9515
Author: Frank Adams
Date: Mon, 06 Oct 1986 00:17
26 lines
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
#9478
Author: Gregory Smith
Date: Mon, 06 Oct 1986 14:48
23 lines
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
#9516
Author: John Woods, Software
Date: Tue, 07 Oct 1986 19:43
28 lines
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
#9553
Author: Guido van Rossum
Date: Sat, 11 Oct 1986 12:30
25 lines
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
#9555
Author: mcg
Date: Sun, 12 Oct 1986 22:22
29 lines
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
#9659
Author: Lawrence W. McVoy
Date: Mon, 27 Oct 1986 06:38
37 lines
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
#9663
Author: andy
Date: Tue, 28 Oct 1986 08:11
31 lines
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