[comp.lang.c] #define DEBUG...

gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) (05/03/90)

I want to have a DEBUG flag which controls whether diagnostic printfs
are executed or not.

The obvious way to do this is:

#ifdef DEBUG
	printf ("debugging information");
#endif DEBUG

But its a pain to have to type the #ifdef ... #endif all the time, and
its less readable than simply having:

	DEBUG ("debugging information");

Now, I can use the latter format if I

#define DEBUG printf

but then how do I turn DEBUG off?


I have though of doing the following (which is not very elegant but I
thought it would work):

#ifdef DODEBUG
#   define DEBUG printf
#   define ENDDEBUG ;
#else
#   define DEBUG /*
#   define ENDDEBUG */
#endif DODEBUG


which would allow the following syntax for debugging

	DEBUG ("the value is %d", val); ENDDEBUG

Unfortunately, I can't figure out how to #define something to be equal
to "/*" sinece "/*" always seems to be interpreted as the start of a
comment.

Well, I've been rambling trying to describe the problem.  Basically,
does anyone have an idea how I can do the above easily and elegantly?

Thanks for reading.

- Jeff
	

gordon@mimir.cs.cornell.edu (Jeffrey Adam Gordon) (05/03/90)

I forgot to mention, the DEBUG should take an arbitrary number of arguments
(just like printf).

- Jeff

wallyk@tekfdi.FDI.TEK.COM (Wally Kramer) (05/04/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon)
writes:

>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.

How about writing your diagnostic statements "thusly":

	DEBUG (("informative message #1: j = %d, k = %d", j, k));
		/* note extra parens surrounding normal printf parameters */

To enable debugging statements:

	#define	DEBUG(x)	printf x

To disable:

	#define	DEBUG(x)

Lint note:  you should define debug on when you run this through lint.

wallyk@tekfdi.fdi.tek.com (Wally Kramer)
Contractor to Tektronix from Step Technology, Inc.  503 244 1239

thornley@cs.umn.edu (David H. Thornley) (05/04/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.
>
>The obvious way to do this is:
>
>#ifdef DEBUG
>	printf ("debugging information");
>#endif DEBUG

How about
#ifdef DEBUG
#define D(X) X
#else
#define D(X)
#endif

and 
D(printf("debugging information\n");)

If DEBUG is defined, anything in D() is used as is; if not, anything in
D() is disregarded.  It seems to work for me.

David Thornley

CMH117@psuvm.psu.edu (Charles Hannum) (05/04/90)

#ifdef DEBUG
#define  debug(x)  printf x
#else
#define  debug(x)
#endif


Then, you can just use something like:

  debug(("%s\n","This is a test."));      (<===  This is an EXAMPLE; it's not
                                                 meant to be efficient, just
                                                 to emphasize the syntax!!!!)

in your code.  Just like printf(), except you need *two* parentheses around
the argument list.

I've been using this trick for years.


Virtually,
- Charles Martin Hannum II         PennMUD Design Team - (Resident) Programmer
    (That's Charles to you!)       "Those who say a thing cannot be done should
  Please send mail to:              under no circumstances stand in the way of
  hannum@haydn.psu.edu              he who is doing it." - a misquote

karl@MorningStar.Com (Karl Fox) (05/04/90)

In article <40628@cornell.UUCP> gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:

   I want to have a DEBUG flag which controls whether diagnostic printfs
   are executed or not.

   The obvious way to do this is:

   #ifdef DEBUG
	   printf ("debugging information");
   #endif DEBUG

   But its a pain to have to type the #ifdef ... #endif all the time, and
   its less readable than simply having:

	   DEBUG ("debugging information");

   Now, I can use the latter format if I

   #define DEBUG printf

   but then how do I turn DEBUG off?


Here is a not-too-gross method I have seen suggested (and used):

    # define DEBUG(a) printf a

or, to disable it,

    # define DEBUG(a)

Then, call it with a double set of outer parentheses:

    DEBUG(("Warning: user %s has an ugly face!\n", user_name));

It even works as the THEN clause of an IF statement.
--
Karl Fox, Morning Star Technologies               karl@MorningStar.COM

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/04/90)

Organization: U.S. Army Ballistic Research Laboratory

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>	DEBUG ("debugging information");
>Well, I've been rambling trying to describe the problem.  Basically,
>does anyone have an idea how I can do the above easily and elegantly?

There are several viable approaches, but PLEASE don't carry on this
discussion in all the groups you posted to:
	comp.lang.c,comp.unix.wizards,alt.sources,comp.sources.d,misc.misc
when comp.lang.c is the proper forum.

The simplest solution in the terms in which you originally designed
your use of DEBUG is to
	#define DEBUG
or
	#define	DEBUG	(void)
to turn off the printf.

wallace@oldtmr.enet.dec.com (Ray Wallace) (05/04/90)

In article <4247@tekfdi.FDI.TEK.COM>, wallyk@tekfdi.FDI.TEK.COM (Wally Kramer)
writes...
>In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon)
>writes:
>>I want to have a DEBUG flag which controls whether diagnostic printfs
>>are executed or not.
>	DEBUG (("informative message #1: j = %d, k = %d", j, k));
>		/* note extra parens surrounding normal printf parameters */
Why not just do this -

#define	BITCH				/* IE: don't print it */
#define	DEBUG printf			/* IE: do print it */
main( )
{
  BITCH( "What the <%s> is going on?\n", "hell" );
  DEBUG( "%d - nothing.\n%d - something.\n", 1, 2 );
}
When the "debug" macro is defined as nothing then the stuff in paranthesis
gets eveluated as an expresion(s) but thats all. When the "debug" macro is
defined as printf then your standard function call to printf occurs. There is
no need for an extra set of parenthesis.

---
Ray Wallace		
		(INTERNET,UUCP) wallace@oldtmr.enet.dec.com
		(UUCP)		...!decwrl!oldtmr.enet!wallace
		(INTERNET)	wallace%oldtmr.enet@decwrl.dec.com
---

randy@csseq.cs.tamu.edu (Randy Hutson) (05/04/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) wri
tes:

>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.

I use something like the following:

#ifdef DEBUG
#define DPRINTF printf
#else
#define DPRINTF if(0) printf
#endif

Now there's no need to put an extra set of parentheses about DPRINTF's
arguments.  As for any efficiency concerns, no compiler I regularly
use (gcc, Sequent cc, and sun cc) generates an explicit comparison
to 0.  However, they do leave in the dead code (calls to printf) unless
the optimizer is invoked, so this method could make your executables
larger if your C compiler doesn't have an optimizer which eliminates
dead code.

escher@Apple.COM (Michael Crawford) (05/04/90)

In article <1990May3.192347.12973@cs.umn.edu> thornley@cs.umn.edu (David H. Thornley) writes:
>In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>>I want to have a DEBUG flag which controls whether diagnostic printfs
>>are executed or not.
>>
>>The obvious way to do this is:
>>
>>#ifdef DEBUG
>>	printf ("debugging information");
>>#endif DEBUG
>
>How about
>#ifdef DEBUG
>#define D(X) X
>#else
>#define D(X)
>#endif
>
>and 
>D(printf("debugging information\n");)

more elegant still:

#ifdef DEBUG
#define fDebug( x ) fprintf x
#define Debug( x ) printf x
#else
#define fDebug( x )
#define Debug( x )
#endif

fDebug(( stderr, "debugging info" ));
Debug(( "debugging info" ));

be sure to do the defining of DEBUG on the CC command line, with a nifty
setup in your makefile:

D=

CFLAGS = ${D}

foo: foo.o
	cc -o foo foo.o

foo.o: foo.c
	cc -c ${CFLAGS} foo.c

Then your command line might be:

alias md 'make D=-DDEBUG'
touch foo.c
md

and you will turn on debugging in foo.c.

Read Robert Ward's book "Debugging C".  It is a gold mine.  Mostly oriented
toward DOS, but much of what is in it is applicable anywhere.

Also, get a source level debugger.  You may have sdb or dbx on Unix systems,
SADE or ThinkC on Macintosh, or Codeview, and I think Turbo C, on the PC.  
The Free Software Foundation's GDB is available for Unix for free and is
much better than dbx or sdb, IMHO.

When you learn to use them effectively, it is a lot better than embedding
code in your source -- less recompiling.
-- 
Michael D. Crawford
Oddball Enterprises		Consulting for Apple Computer Inc.
606 Modesto Avenue		escher@apple.com
Santa Cruz, CA 95060		Applelink: escher@apple.com@INTERNET#
oddball!mike@ucscc.ucsc.edu	The opinions expressed here are solely my own.

		Free Lithuania.

ronnie@mindcrf.UUCP (Ronnie Kon) (05/04/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.
>		[ lots of stuff deleted ]

	How about:

#if WANT_DEBUGGING
#	define	DEBUG(a,b,c,d,e)	printf(a,b,c,d,e)
#else
#	define	DEBUG(a,b,c,d,e)
#endif

This is ugly, in that you must always supply a fixed number of parameters,
but it's quick and easy.  You can also use multiple definitions, DEBUG1,
DEBUG2, etc, each taking a different number of parameters.

	If your application is not real-time, you can also make DEBUG a real
routine, which does nothing if your definition is not turned on, and a printf
if it is.  This causes an overhead of a few microseconds on an average
machine (say a 10MHz 68000) each call.

	Hope this helps.

				Ronnie
-- 
-------------------------------------------------------------------------------
Ronnie B. Kon                    |  "The answers to life's problems aren't at
kon@mindcraft.com                |  the bottom of a bottle: they're on TV!"
...!{decwrl,ames}!mindcrf!ronnie |               -- Homer Simpson
-------------------------------------------------------------------------------

jik@athena.mit.edu (Jonathan I. Kamens) (05/04/90)

In article <1717@engage.enet.dec.com>, wallace@oldtmr.enet.dec.com (Ray
Wallace) 
writes:
|> Why not just do this -
|> 
|> #define	BITCH				/* IE: don't print it */
|> #define	DEBUG printf			/* IE: do print it */
|> main( )
|> {
|>   BITCH( "What the <%s> is going on?\n", "hell" );
|>   DEBUG( "%d - nothing.\n%d - something.\n", 1, 2 );
|> }

  Because it's sloppy and causes good compilers to complain.  Compiling
your program on an IBM RT/PC running AOS4.3 with MetaWare's High C
compiler (version 2.1y) works, but produces the following warnings:

    w "foo.c",L5/C8:        "What the <%s> is going on?\n"
    |    Expression has no side-effects.
    w "foo.c",L5/C8:        Expression has no side-effects.

It's stupid to write code that makes the compiler bitch when it's
possible to accomplish the same purpose without the compiler complaining
at all.  The more a compiler is forced to bitch, the more programmers
come to expect compiler error messages, and therefore the less seriously
they take them.

  I personally make it a policy never to write any "real" code (i.e.
code that I expect anyone else to ever see; and please let's not get
into the debate of one-time-only programs again) that won't compile with
High C without any errors.  I wish more programmers had better compilers
to check their code with, and/or ran their code through lint more often,
because it's a rare program I get off the net that doesn't cause
compiler errors or warnings when I compiler it on my system.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (05/04/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
| I want to have a DEBUG flag which controls whether diagnostic printfs
| are executed or not.

#ifdef	DEBUG
#undef DEBUG /* prevent warning from redef */
#define DEBUG(x) printf x
#else
#define DEBUG(x)
#endif

To use:

	DEBUG(("Any # of args: %d\n", whatever));

  The secret is in having the 2nd level of parens in the invocation of
DEBUG and no parens in the expansion. Works like a charm!
-- 
bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen)
    sysop *IX BBS and Public Access UNIX
    moderator of comp.binaries.ibm.pc and 80386 mailing list
"Stupidity, like virtue, is its own reward" -me

dig@peritek.UUCP (Dave Gotwisner) (05/04/90)

In article <40628@cornell.UUCP>, gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:
> I want to have a DEBUG flag which controls whether diagnostic printfs
> are executed or not.
> 
> The obvious way to do this is:
> 
> #ifdef DEBUG
> 	printf ("debugging information");
> #endif DEBUG
> 
> But its a pain to have to type the #ifdef ... #endif all the time, and
> its less readable than simply having:
>
> 	DEBUG ("debugging information");

Agreed.

> 
> Now, I can use the latter format if I
> 
> #define DEBUG printf
> 
> but then how do I turn DEBUG off?

Having read some of the other responses, I have yet to see the one I use:

#ifdef DEBUG
# define	Dprintf	printf
#else
# define	Dprintf if
#endif

This only needs to be included in a common header file,  then, if you do:

	Dprintf("Input value is %d\n", 10);

you get the following if DEBUG is defined:

	printf("Input value is %d\n", 10);

and the following if DEBUG is not defined:

	if ("Input value is %d\n", 10);

The semicolon will terminate the if, so, unless the debug printf has an
else immediatly after it, this will work.  There is some run time overhead
(unless your compiler optimizes "if (statement);" away because it never does
anything), but the overhead should be small.
-- 
------------------------------------------------------------------------------
Dave Gotwisner					UUCP:  ...!unisoft!peritek!dig
Peritek Corporation				       ...!vsi1!peritek!dig
5550 Redwood Road
Oakland, CA 94619				Phone: 1-415-531-6500

dsmythe@netcom.UUCP (Dave Smythe) (05/04/90)

It seems to me that if you want to go the instrumentation route, as opposed
to the debugger route, then you might want to look at the dbugsys package
(I think that there were at least 2 kinds) posted a while back to c.s.misc
or c.s.unix.  If I recall correctly, it does all of that kind of DEBUG stuff
as well as giving you run-time control of the level of debugging info that
you want to see (foo -x4 , or something like that).  There were quite a
variety of functions there for many other purposes as well.

D

dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (05/04/90)

In article <90123.152729CMH117@psuvm.psu.edu> CMH117@psuvm.psu.edu (Charles Hannum) writes:
>
>#ifdef DEBUG
>#define  debug(x)  printf x
>#else
>#define  debug(x)
>#endif
>

On UNIX you might want to do something like:

#ifdef DEBUG
#define debug(x)   	printf x, fflush (stdout)
#else
#define debug(x)
#endif

or put an
#ifdef DEBUG
setbuf (stdout, NULL);
#endif 

near the beginning of main. Otherwise you have no way of knowing
where in the program it crashed.



--
Dave Eisen                      	    Home: (415) 323-9757
dkeisen@Gang-of-Four.Stanford.EDU           Office: (415) 967-5644
"I drive a brand new BMW and I wear an unusually large shoe..."

rob@icarus.inmos.co.uk (Robin Pickering) (05/04/90)

In article <1717@engage.enet.dec.com> wallace@oldtmr.enet.dec.com (Ray Wallace) writes:
>
>Why not just do this -
>
>#define	BITCH				/* IE: don't print it */
>#define	DEBUG printf			/* IE: do print it */
>main( )
>{
>  BITCH( "What the <%s> is going on?\n", "hell" );
>  DEBUG( "%d - nothing.\n%d - something.\n", 1, 2 );
>}

The trouble with this approach is that the debug strings and the cost of
evaluating the expr, still get compiled in whether debug is on or not.
This may not be a problem in some applications, but if you don't mind the
debug information always being in the code then why not turn it on at runtime
by making DEBUG a function whose operation is controlled by a runtime switch
(much more flexible and at least there is the possibilty of making those
 compiled in strings work for a living occaisionally).

If you do use the above approach, might I suggest:
#define BITCH (void)   /* IE: do nothing, but dont make lint scream about
                          each debug line */


 Rob Pickering.
--
JANET:     ROB@UK.CO.INMOS                      | Snail: 1000 Aztec West
Internet:  rob@inmos.com                        |        Almondsbury
Path:      ukc!inmos!rob or uunet!inmos-c!rob   |        Bristol BS12 4SQ
Phone:     +44 454 611638                       |        UK

silvert@cs.dal.ca (Bill Silvert) (05/04/90)

In the recent postings there were a number of solutions to the problem
of defining a function DEBUG which optionally works like printf.  Only
one addresses the fact that debugging information should preferably go
to stderr:

In article <8060@goofy.Apple.COM> escher@Apple.COM (Michael Crawford) writes:
>more elegant still:
>
>#ifdef DEBUG
>#define fDebug( x ) fprintf x
>#define Debug( x ) printf x
>#else
>#define fDebug( x )
>#define Debug( x )
>#endif
>
>fDebug(( stderr, "debugging info" ));
>Debug(( "debugging info" ));

Is there a way to define Debug so that Debug(x, y, z,...) can optionally
either do nothing or generate fprintf(stderr, x, y, z,...) with an
arbitrary number of arguments?  Crawford's method still requires
specific mention of stderr in each debug line.

-- 
William Silvert, Habitat Ecology Division, Bedford Inst. of Oceanography
P. O. Box 1006, Dartmouth, Nova Scotia, CANADA B2Y 4A2.  Tel. (902)426-1577
UUCP=..!{uunet|watmath}!dalcs!biomel!bill
BITNET=bill%biomel%dalcs@dalac	InterNet=bill%biomel@cs.dal.ca

jmoore@cidmac.ecn.purdue.edu (James D Moore) (05/04/90)

In article <1717@engage.enet.dec.com> wallace@oldtmr.enet.dec.com (Ray Wallace) writes:
>
>In article <4247@tekfdi.FDI.TEK.COM>, wallyk@tekfdi.FDI.TEK.COM (Wally Kramer)
>writes...
>>In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey Adam Gordon)
>>writes:
>>>I want to have a DEBUG flag which controls whether diagnostic printfs
>>>are executed or not.

Several people have pointed out several ways to use the #define to 
equate DEBUG to printf. I personaly feel that using the standard
#ifdef and using the the "-D<flag>" option at compile time is the
best way to do it. Am I missing something here ? I do this with
different levels of debugging so I can have several flags. Anyway
that is my $0.2 worth.

Jim Moore
Purdue University
jmoore@cidmac.ecn.purdue.edu

passaret@brahe.crd.ge.com ("Mr. Mike" Passaretti) (05/04/90)

In article <40628@cornell.UUCP> 
gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:
#
#    I want to have a DEBUG flag which controls whether diagnostic printfs
#    are executed or not.
#
#	 [....]
#
#    - Jeff

Fred Fish has produced an excellent set of macros for C
which do just this and a lot more.  The basic form of use is
as follows (forgive me if this is a bit long).

    #include "dbug.h"

	main(argc, argv)
	int argc;
	char *argv[];
	{
	int foo;

	DBUG_ENTER("main");
	DBUG_PROCESS(argv[0]);
	for (i=1;i<argc && argv[i][0]=='-';i++)
            {
		switch(argv[i][1])
		{
		case '#' :
		    {
		    DBUG_PUSH(&(argv[i][2]));
		    }
		    break;
		[...]
		}
	    }

	foo = bar_bar_bar();
	DBUG_PRINT("bar", ("Foo = %d\n", foo));

	foo = blah_blah_blah();
	DBUG_PRINT("blah", ("Foo = %d\n", foo));
	DBUG_VOID_RETURN(0);
	}	

Now, at run-time the program can be called with a command
line like 'a.out #d:t mumble'.   This is a flag which the
DBUG macros use (through DBUG_PROCESS and DBUG_PUSH) to
enable and disable various functions.  There is tracing,
which is an output like

	>main
	->bar_bar_bar
	-<bar_bar_bar
	->blah_blah_blah
	-<blah_blah_blah
	<main

for simple level tracing.  There is also "flag" type printf
enabling, where a command line like 'a.out #dbar,:t mumble'
would cause all DBUG_PRINTFs with the keyword (1st arg)
"bar" to get printed.  There are also global enables and
disables, including the #define DBUG_OFF, which removes all
of the debug code entirely (for production usage).

my dbug.h has the following author notice in it, but I think
it's outdated.  Fred's whereabouts should be easy to
determine, if by no other method than eavesdropping on
 comp.sys.amiga for a while.

  *  AUTHOR
  *
  *	Fred Fish
  *	(Currently employed by Motorola Computer Division, Tempe, Az.)
  *	hao!noao!mcdsun!fnf
  *	(602) 438-3614

                                                        - MM

-- 
passaretti@crd.ge.com                     {whatever}!crdgw1!brahe!passaret

rosenber@ra.abo.fi (Robin Rosenberg INF) (05/04/90)

>I want to have a DEBUG flag which controls whether diagnostic printfs 
>are executed or not.                                                  

I have used the following macros for a while now and they work fine.

/* tdebug.h  -- tracing & debugging macros
 *
 */
#if TDEBUG
    #define T(s)        {dprintf("\033[33m(\033[0m%s\033[0m",#s);{s} dprintf("\033[33m)\033[0m\r\n");}
    #define D(s)        s
    #define P(a)        dprintf a
    #define V(n,x)      {if (debuglevel>=n) dprintf("%s\r\n",x);}
#else
    #define T(s)        {s}     /* ! trace execution of statements */
    #define D(s)        ;       /* ! execute only when debugging */
    #define P(a)                /* ! printf when debugging */
    #define V1(n,x)     {}
#endif TDEBUG
/* eof */

dprintf has the same synopsis as printf, however if may be some other
function. Which function it is is defined at link time. Usually dprintf asks
another process to print the debugging info for me. If your system does not
allow you to define symbols at link time, replace dprintf with the funtion
you want in tdebug.h

Note however that the T() macro doesn't work in all cases. Most notably it
may have to be written differently for other compilers and may not work if
the statement beging traced contains double quotes.

Also, the ANSI escape sequences used in the T() macro is to help matching
parentheses in the trace output.

Here is a sample (not useful) program using these macros

#define TDEBUG 1	/* or 0 if debugging is not wanted */
#include "tdebug.h"

int debuglevel;

main(int argc,char **argv)
{
	debuglevel = atoi(argv[1]);
	P(("This is a demo. Prog =%s\n",argv[0]));
	T(subroutine(argc,argv);)
	V(1,"I will now fall off the e");
}

You may use or modify these macros as you like according to your needs.
Enjoy!

-----------
Robin Rosenberg

travis@cs.columbia.edu (Travis Lee Winfrey) (05/04/90)

In article <40628@cornell.UUCP>, 
>gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>
>    I want to have a DEBUG flag which controls whether diagnostic printfs
>    are executed or not.

Well, another variation on the debug macro with two parentheses
is to have a first argument that specifies the current level of
interest.  This argument can be compared with whatever you need: a
module-specific #define, a module-specific variable, a global
variable.  The two biggest problems with this method are the complaints
from lint about constants appearing in an if-statement, and that some
compilers may not strip out the code when you don't want the output.

A sample follow.  Note that the numbers here range from 1 to 4 because
I define DEBUG on a per-module basis.  Some other people specify their
interest in debugging information in terms of percentages, i.e., show
me 50% of everything you have in this module.  that's not intuitive
for me.

(I'm sorry if anyone else has already described this particular
fillip; I looked through all the messages posted so far, as many of
the previous posters should have done.)

/* 
 * debugging macros.  the dprintf macro takes two arguments, a
 * debugging level (1, 2, 3, 4) and a list of ordinary printf
 * arguments in parentheses, e.g.,
 *	dprintf(1, ("proc_kill_module: sys_ptr is NULL!\n"));
 * 
 * debugging levels:
 *     level 1: ordinary unexpected events which the programmer may want
 *              to know, but a user will not.  all "oh no!" type
 * 		information should be marked with this.
 *     level 2: more detailed, usually per-module information that
 * 		will a programmer will not want to know *unless* he or
 * 		she is debugging that module.
 *     Level 3: more detailed than 2, usually per-procedure
 * 		debugging information.  debugging statements this
 * 		low-level will be removed once gross errors are
 * 		found and removed.
 *     Level 4: just a level for demarcating extremely low-level,
 * 		usually inner-loop information.  removed as level 3 messages.
 *              
 */
# ifdef DEBUG
#       define dprintf(dlevel,printfargs)  if (dlevel <= DEBUG ) \
						printf printfargs  
# else /* DEBUG */
#	define dprintf(a,b)
# endif /* DEBUG */
--

Arpa:	travis@cs.columbia.edu	Usenet: rutgers!columbia!travis

tif@commlab1..austin.ibm.com (/32767) (05/05/90)

In article <40628@cornell.UUCP> gordon@cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.
>	DEBUG ("debugging information");
>but then how do I turn DEBUG off?

Actually it's easier than you thought:
	#define DEBUG
will turn it off although the string will still be put in your
executable (unless your optimizer is better than mine).  ("xx")
is a parenthesised pointer expression which is a valid C statement.

Most people I know of do
	#define DEBUG(xx)	printf xx
and then
	DEBUG(("the flag is %d\n", flag));
The whole thing is completely removed with
	#define DEBUG(xx)

Paul Chamberlain
tif@doorstop.austin.ibm.com
tif@commlab1.austin.ibm.com
sc30661@ausvm6

bjstaff@zds-ux.UUCP (Brad Staff) (05/05/90)

I add some declarations that look something like the following:

#ifdef	PRODUCTION
#define	DEBUG	0
#else
int	DEBUG = FLAG1 | FLAG2 | ... | FLAGn;
#endif	/* PRODUCTION */

Then I do it like this:

	if (DEBUG & FLAGx)
		printf(...);

This way the debug statements look more like regular C code, which is more
aesthetically pleasing to my eyes.  :-)  This method allows you to turn debug
printfs on and off in a running system by patching the DEBUG variable with a
kernel debugger or adb.  When you #define PRODUCTION, any compiler worth using
(IMHO) will optimize away both the test and the printf itself, for a zero
performance penalty.
-- 
Brad Staff               |
Zenith Data Systems      | "A government that can forbid certain
616-982-5791             |  psychoactive drugs can mandate others."
bjstaff@zds-ux.zds.com   |	- Russell Turpin

jkimble@nostromo.austin.ibm.com (The Programmer Guy) (05/05/90)

> [quick DEBUG method within programs]


Here's how I usually do it:

#define DEBUG(l, f, s)	if (Debug >= l) fprintf(stderr, f, s)

You will have to have "int Debug;" somewhere, usually as a global.

Now you just change (int)Debug to be whatever you want;  I usually
have a command-line option that allows me to specify it in levels (ala
UUCP).  For example:    program -x9   (Debug will be set to 9, maximum debug)
			program -x5   (Debug will be set to 5, medium debug)
			program -x1   (Debug will be set to 1, minimum debug)

Your DEBUG statements look like so within the program:

	DEBUG(7, "Number of elements within array = %d\n", nmbr);
	DEBUG(5, "Pointer a = |%s|\n", a);
	etc., etc., etc.,

Caveats:

	If you just have an information message and don't want any
	data passed, make sure you do something like this:

	DEBUG(7, "We're in rmdir()...\n", "");

	[note the second set of ""]

The final caveat is that you can only pass one parameter per DEBUG()
statement;  therefore if you have multiple variables to print you're
going to have to use more than one DEBUG statement.  However, I think
this is the cleanest way to handle this sort of stuff.  (But I am sure
we're going to see plenty of other methods coming back from The Net).

Hope this helps!
--Jim Kimble,				Phone: 512/823-4479 (work)
Yet Another IBM Contractor		UUCP: ibmaus!jkimble@cs.utexas.edu
TCP/IP Development, 			RISC System/6000, RT++, RS/6000, etc.
IBM Austin, TX

"ALPO is 99 cents a can.  That's almost SEVEN dog dollars!"

new@udel.EDU (Darren New) (05/05/90)

>>gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>>
>>    I want to have a DEBUG flag which controls whether diagnostic printfs
>>    are executed or not.

I have a version that interactively lets you specify the level of detail
desired, allows part or all to be redirected to the printer or a file,
and so on.   It is somewhat AmigaDOS specific in terms of I/O handling,
but if you can open a separate window on your platform, it shouldn't
be a problem.  If anybody wants it, let me know and I will post it to
someplace appropriate (alt.sources.amiga?)         -- Darren

wayne@ultra.com (Wayne Hathaway) (05/05/90)

travis@cs.columbia.edu (Travis Lee Winfrey) suggests:

  # ifdef DEBUG
  #       define dprintf(dlevel,printfargs)  if (dlevel <= DEBUG ) \
                                                  printf printfargs  
  # else /* DEBUG */
  #       define dprintf(a,b)
  # endif /* DEBUG */

A good idea, and one which I also use (slightly more generalized, of
course; I just can't resist getting too damn fancy for my own good!).


I do have one nit, though:  I would suggest defining "dprintf" as:

    define dprintf(dlevel,printfargs)  if (dlevel > DEBUG) ; \
                                       else printf printfargs

Why?  Consider the following:

        if ( <some_strange_situation> )
            dprintf(1, ("oh no! just had some strange situation\n"));
        else
            <regular_processing>;


You see, I just HATE programs that stop working when you turn on the
DEBUG flag!  :-)

wayne

  Wayne Hathaway            
  Ultra Network Technologies     domain: wayne@Ultra.COM
  101 Daggett Drive            Internet: ultra!wayne@Ames.ARC.NASA.GOV
  San Jose, CA 95134               uucp: ...!ames!ultra!wayne
  408-922-0100

gar@spiff.UUCP (Gordon Runkle) (05/05/90)

In article <40628@cornell.UUCP> gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:

   I want to have a DEBUG flag which controls whether diagnostic printfs
   are executed or not.

   But its a pain to have to type the #ifdef ... #endif all the time, and
   its less readable than simply having:

	   DEBUG ("debugging information");

   Now, I can use the latter format if I

   #define DEBUG printf

   but then how do I turn DEBUG off?

   I have though of doing the following (which is not very elegant but I
   thought it would work):

   [ valiant attempt...]

There is a simple solution.  Get the book "Debugging C" by Robert Ward
(Que, Indianapolis, Indiana, ISBN: 0-88022-261-1).

On page 106 is an example of exactly your problem.  I will explian it,
but I strongly recommend you buy the book.  It's very useful.

#ifdef TESTING
# define TRACE(args)	fprintf args
#else
# define TRACE(args)
#endif

This macro means that TRACE(args) will have a value if TESTING is
defined.  Otherwise, TRACE(args) will have no value, and the
preprocesor will eliminate it.  You want args to be affected too,
for obvious reasons.

When you use it, use *2 sets* of parentheses around the args, to
insure that the entire list of args is given to fprintf():

main(argc, argv)
int argc;
char *argv[];
{

TRACE((stderr, "argc is %d\n", argc));
if (argc > 1)
	printf ("hello world\n");
}

In this example, if TESTING is defined, the TRACE statement will be
converted to:

fprintf (stderr, "argc is %d\n", argc);

otherwise, it will be reduced to ";", an empty statement.  
It's pretty simple, really.  Again, I really recommend the book.

-=gordon=-   <Gordon Runkle>
--
UUCP:  uunet!men2a!spiff!gar        ARPA:  men2a!spiff!gar@uunet.uu.net
Management Information Consulting, Inc.          HOME PH:  703-522-0825
2602 Lee Hwy, # 204,  Arlington, VA  22201       WORK PH:  202-566-4382

	"Just once I'd like to run across an alien menace that
	isn't immune to bullets."	-- The Brigadier

markb@giga.slc.unisys.com (Mark Baranowski) (05/05/90)

References: <11290@hoptoad.uucp> <40628@cornell.UUCP> <1427@peritek.UUCP>

Has any one of you knuckleheads posting followups to this thread taken
a look at the header and realized what groups you are cross posting to?

I have deleted the cross postings from the newsgroups in this article
so as not to further this distribution of this asinine thread, but
here is what it said:
 
 Newsgroups: comp.lang.c,comp.unix.wizards,alt.sources,comp.sources.d,misc.misc
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Do you think the unix wizards want to ponder the nifty things you can do 
with defines?

Do you think people want to read about defines in alt.sources where only
source code and nothing else is to be posted?

Is this a discussion about some piece of source code in comp.sources?
(comp.sources.d is for discussions about any old piece of software, right?)

This is certainly miscellaneous information so why not include misc.misc,
right?

Anyone who posts a follow up to an article without checking the relevancy
of the Newsgroups being cross-posted to is a knucklehead.

-- 
Internet: markb@slc.unisys.com			uucp: ...!giga!markb
	  markb@signus.utah.edu

Quote:    Mutate or die! -- Howard Faxon

kc@oz.rci.dk (Knud Christensen) (05/07/90)

gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:

>I want to have a DEBUG flag which controls whether diagnostic printfs
>are executed or not.

>The obvious way to do this is:

>#ifdef DEBUG
>	printf ("debugging information");
>#endif DEBUG

>But its a pain to have to type the #ifdef ... #endif all the time, and
>its less readable than simply having:

>	DEBUG ("debugging information");

>Now, I can use the latter format if I

>#define DEBUG printf

>but then how do I turn DEBUG off?


>I have though of doing the following (which is not very elegant but I
>thought it would work):

>#ifdef DODEBUG
>#   define DEBUG printf
>#   define ENDDEBUG ;
>#else
>#   define DEBUG /*
>#   define ENDDEBUG */
>#endif DODEBUG


>which would allow the following syntax for debugging

>	DEBUG ("the value is %d", val); ENDDEBUG

>Unfortunately, I can't figure out how to #define something to be equal
>to "/*" sinece "/*" always seems to be interpreted as the start of a
>comment.

>Well, I've been rambling trying to describe the problem.  Basically,
>does anyone have an idea how I can do the above easily and elegantly?

>Thanks for reading.

>- Jeff
>	
The following, which i found in a magazine solves the problem very elegantly i
think:

/*
  debug.h

  This header file gives a number of usefull definitions for debugging
*/

#ifdef debug
#  define DFPRINTF(x) fprintf x
#  define DTRACE fprintf(stderr, "Trace line %d\n", __LINE__)
#  define DTRINT(var) fprintf(stderr, "Trace line %d var = %d\n", __LINE__, var)
#else
#  define DFPRINTF(x)
#  define DTRACE
#  define DTRINT(var)
#endif

/*
  End of debug facility definitions
*/

C-program

#define debug
#include "debug.h"

int i,j;

main()
{
  DFPRINTF((stdout,"This is a test %d", i));
}
----

Knud Christensen                                     RC International, Denmark
kc@rci.dk

It is better to keep your mouth shut, and look like a fool
 than to open it, and remove all doubt!   - Marx - (Groucho not Karl).

tsnider@enprt.Wichita.NCR.COM (Tim Snider) (05/07/90)

I was reading the stuff about DEBUG and here's what we do:

#define DEB(n,a)  if ( ldebug > n ) prt a

The debugs can be turned on and off interactively by setting n to the desired
value.  You don't have to take old debug statements out just turn up the value
for n so they won't print.  The prt function is just a shell for the appropriate
printf or fprintf statements depending on where/how the code is being executed.
A typical DEBUG statment looks like:

DEB (0, (" glorp %x glob %x splat %x", glorp, glob, splat));

The only negative thing about this method is that braces must be used
around ifs etc.
-------------------------------------------------------------------------
Tim Snider
NCR Peripherial Products Div.
Wichita Ks.
tsnider@wichita.NCR.COM

robwah@auto-trol.UUCP (Robert Wahl) (05/08/90)

William Silver writes:
>Is there a way to define Debug so that Debug(x, y, z,...) can optionally
>either do nothing or generate fprintf(stderr, x, y, z,...) with an
>arbitrary number of arguments?  Crawford's method still requires
>specific mention of stderr in each debug line.

Consider the basic setup which is required to use a variable argument list in
a macro.  The list must be used as the argument list of a function call, and
no other arguments can be added.  However, that function need not be printf:

#ifdef DEBUG
#define DPRINTF(list) (dprintf list)
#else
#define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */
#endif

DPRINTF ((fmtstr, arg1, arg2, arg3));

Writing "dprintf" is left as an exercise for the reader.  Using assembly
language, it may be an easy thing to prepend stderr to the variable argument
list and then call "fprintf".  Most likely, though, you will have to parse the
format string for the number and type of arguments in order to set up the
call to "fprintf".  If so, you might as well do it all in C (which at least
is portable), and do your output in stages.

Here's a simply coded, but dreadfully hacky solution:  temporarily replace
stdout with stderr, then use printf as suggested before.  This is inherently
non-portable, inefficient, risky and generates lots of code.

#ifdef DEBUG
static FILE dprintf_stdout;
static int dprintf_retval;
#define DPRINTF(list) (dprintf_stdout = *stdout, *stdout = *stderr, \
	dprintf_retval = printf list, *stdout = dprintf_stdout), dprintf_retval)
#else
#define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */
#endif

If you do use this method, forget that you heard of it from me.

Perhaps the best solution is just to use fixed argument lists; after all, how
many values do you typically output in one debug statement?

#ifdef DEBUG
#define Debug0(fmt)		(fprintf (stderr, fmt))
#define Debug1(fmt,val1)	(fprintf (stderr, fmt, val1))
#define Debug2(fmt,val1,val2)	(fprintf (stderr, fmt, val1, val2))
...
#else
#define Debug0(fmt)		(1)
#define Debug1(fmt,val1)	(1)
#define Debug2(fmt,val1,val2)	(1)
...
#endif

Debug3 ("Name is %s, value is %d (0x%x)\n", name, val, val);
	or
Debug1 ("Name is %s, ", name);  /* Note lack of newline in format string */
Debug2 ("value is %d (0x%x)\n", val, val);
-- 
Rob Wahl  =:->  {robwah@auto-trol.com | ...!ncar!ico!auto-trol|robwah}

versto@cs.vu.nl (Verstoep C) (05/08/90)

About one year ago a public domain package written by Fred Fish,
appropriately called DBUG, appeared on the net.
It's main feature is that it you can select, as a commandline option,
the debug statements you want. For example (just snapped from another window):

        DBUG_PRINT("cluster", ("re-evaluating parameter `%s'",
			       param->par_idp->id_text));
or
	DBUG_EXECUTE("objects", { PrintObject(obj); });

On the commandline you can then say (amake being the program I'm working on):

	amake -%d,cluster
or
	amake -%d,cluster,objects

which means that only the debug statements with the keywords mentioned will
be executed. As shown above, a debug statement can be a generic print statement
or an arbitrary piece of code by means of a DBUG_EXECUTE.
If the program is compiled with the -DDBUG_OFF flags, all debugging code
is automatically excluded, so you'll never have to remove a debug statement
for efficiency reasons.
Needless to say, this package is especially great for large programs under
development. Besides the features mentioned it also has a kind of profiler and
function tracer built-in, although I don't use those currently.

If you're interested in the package, you could try to get it from one of
the archives, or else contact me.

Kees Verstoep (versto@cs.vu.nl)

kla@physc1.byu.edu (05/08/90)

I'm Sorry I just couln't resist this discussion. I have been using this
type of Debugging statements for quite some time with a great deal of
success. It all started when CodeView couldn't fit into the same
640K as the rest of my program, but I now use it in even my unix
programs even when I also use a source level debugger.

I tried to use debugging levels, as in:

Debug(level,("%d %c %f",a,b,c));

but found that this was too much of a regimen for me. I finally settled
for the following in a header file.

static int __bug__ = 1;

#define bug(); __bug__ = 1;
#define bugoff(); __bug__ = 0;

#ifdef DEBUG

#define Debug(cmdstr)  if(__bug__) { printf cmdstr ; fflush(stdout); }

#else

#define Debug(cmdstr)

#endif

The difference between this and the other things offered is slight, but
important for Object Oriented programming. It is the bug() and bugoff()
routines. This way you can debug a certain object WITHIN THE CONTEXT
OF A BIG REAL LIFE PROGRAM without wading through piles of similar
printouts of other already debugged modules.

The __bug__ variable is defined as statically global to each and
every module separately. This is a fine point, but it is important.

Also, if you get into the source level debugger, and you find that
there may be a problem in another module which was unexpected, you
can turn on its debugging by toggling its __bug__ variable and watching
the output for a while.

The other thing which no one has mentioned, is that this type of
statement should not be removed from production code. It is very
useful as internal documentation. If a new programmer comes on and
wants to figure out a new piece of code, he can just look at the
Debug statements to find out what was in the mind of the YoYo that
wrote it. He can also turn on the debug statements of one module
to watch how that module interacts with other parts of the program.

This could be made a lot more sophisticated as necessary. Thanks for
your attention for this little addition to the Debug lore.

One thing I haven't figured out yet. How to do this elegantly while
debugging a user interface. Nothings perfect, but a log file might
work by just redirecting stdout since most user interfaces don't
use the standard printf.

-Kelly
-Just a few bats from the belfrey.
kla@batman.byu.edu

fenske@dfsun1.electro.swri.edu (Robert Fenske Jr) (05/08/90)

In article <801@oz.rci.dk> kc@oz.rci.dk (Knud Christensen) writes:
>gordon@mimir.cs.cornell.edu (Jeffrey  Adam Gordon) writes:
>
>>I want to have a DEBUG flag which controls whether diagnostic printfs
>>are executed or not.
>
How 'bout this:

#define DPRINTF(s)	if (DEBUG) printf(s)

which can't be used in "if" statements for example--but still useful--or
this:

#define DPRINTF(s)	(DEBUG ? printf(s) : 0)

with perhaps some compilers complaining about a useless statement when
debug is zero.  DEBUG could be a #define or a variable and can be easily
taken care of on the compiler command line.

-- 
Robert Fenske, Jr.                      Sw     | The Taming the C*sm*s series:
Electromagnetics Division              /R---\  |
Southwest Research Institute          | I    | | "The Martian canals were the
dfsun1.electro.swri.edu 129.162.160.4  \----/  |  Martians' last ditch effort."

jmm@eci386.uucp (John Macdonald) (05/08/90)

In article <2294@awdprime.UUCP> tif@awdprime.austin.ibm.com.UUCP (/32767) writes:
|Most people I know of do
|	#define DEBUG(xx)	printf xx
|and then
|	DEBUG(("the flag is %d\n", flag));
|The whole thing is completely removed with
|	#define DEBUG(xx)

The same sequence has been suggested numerous times in previous
messages.

The double parentheses in this solution are annoying, and error-prone,
and not really required.

Try the following instead:

    #ifdef DEBUG_PRINT_ON
    #   define DEBUG printf
    #else
    #   define DEBUG(ignore)
    #endif

To insert a DEBUG-conditional printf use:

    DEBUG( "format", args, ... );

(no double parens or other funny syntax required, it just looks like
a function call)

If you prefer, you can comment out one of the defines rather than
controlling it with an ifdef.
-- 
Algol 60 was an improvment on most           | John Macdonald
of its successors - C.A.R. Hoare             |   jmm@eci386

robinson (Jim Robinson) (05/09/90)

In article <801@oz.rci.dk> kc@oz.rci.dk (Knud Christensen) writes:
>The following, which i found in a magazine solves the problem very elegantly i
>think:
>
>/*
>  debug.h
>
>  This header file gives a number of usefull definitions for debugging
>*/
>
>#ifdef debug
>#  define DFPRINTF(x) fprintf x
>#  define DTRACE fprintf(stderr, "Trace line %d\n", __LINE__)
>#  define DTRINT(var) fprintf(stderr, "Trace line %d var = %d\n", __LINE__, var)
>#else
>#  define DFPRINTF(x)
>#  define DTRACE
>#  define DTRINT(var)
>#endif
>
>/*
>  End of debug facility definitions
>*/

Isn't the use of __LINE__ non-portable?
-- 
Jim Robinson
{uunet,ubc-cs}!van-bc!mdivax1!robinson

gwyn@smoke.BRL.MIL (Doug Gwyn) (05/09/90)

In article <1990May8.183211.2661@mdivax1.uucp> mdivax1!robinson (Jim Robinson) writes:
>Isn't the use of __LINE__ non-portable?

I guess it depends on your definition of portable.
The C standard requires that __LINE__ be supported by every conforming
implementation.

robinson (Jim Robinson) (05/09/90)

In article <12814@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
>In article <1990May8.183211.2661@mdivax1.uucp> mdivax1!robinson (Jim Robinson) writes:
>>Isn't the use of __LINE__ non-portable?
>
>I guess it depends on your definition of portable.
>The C standard requires that __LINE__ be supported by every conforming
>implementation.

Is this the ANSI C Standard? An admittedly cursory look thru a copy of the
K&R C manual (first edition) did not produce any mention of __LINE__.

And, is __FILE__ required to be supported?
-- 
Jim Robinson
{uunet,ubc-cs}!van-bc!mdivax1!robinson

jmm@eci386.uucp (John Macdonald) (05/09/90)

In article <1990May8.133742.10584@eci386.uucp> I wrote:
|
|The double parentheses in this solution are annoying, and error-prone,
|and not really required.
|
|Try the following instead:
|
|    #ifdef DEBUG_PRINT_ON
|    #   define DEBUG printf
|    #else
|    #   define DEBUG(ignore)
|    #endif
|
|To insert a DEBUG-conditional printf use:
|
|    DEBUG( "format", args, ... );

without checking whether it worked.  Well it used to work back when
I was running on an old system, with an older preprocessor, but
nowadays on many preprocessors you get an error message about a
mismatch in the number of arguments when you have debugging turned
off.

Here I go, crawling into a cave and pulling the opening in after me...
-- 
Algol 60 was an improvment on most           | John Macdonald
of its successors - C.A.R. Hoare             |   jmm@eci386

henley@motcid.UUCP (Aaron Henley) (05/09/90)

kla@physc1.byu.edu writes:

>static int __bug__ = 1;

>#define bug(); __bug__ = 1;
>#define bugoff(); __bug__ = 0;

>#ifdef DEBUG

>#define Debug(cmdstr)  if(__bug__) { printf cmdstr ; fflush(stdout); }

>#else

>#define Debug(cmdstr)

>#endif

>Also, if you get into the source level debugger, and you find that
>there may be a problem in another module which was unexpected, you
>can turn on its debugging by toggling its __bug__ variable and watching
>the output for a while.


Looks pretty good, but I would change it a little to like this:

	#ifdef DEBUG

	static int __bug__ = 1;

	#define bug(); __bug__ = 1;
	#define bugoff(); __bug__ = 0;

	#define Debug(cmdstr)  if(__bug__) { printf cmdstr ; fflush(stdout); }

	#else

	#define Debug(cmdstr)
	#define bug();
	#define bugoff();

	#endif

This way if DEBUG is set off you have no impact at all from the debug
statements.  Also put this code in a special header file "debug.h" so
you can insure that the variables needed are defined properly.  Besides
your macros Debug, bug, and bugoff hide the functionality of the DEBUG
statements so why not hide them all together.

-- 
   ___________________________________________________________________
  /  Aaron Henley, Motorola Inc.      DISCLAIMER: std.disclaimer     /
 / Cellular Infrastructure Division   UUCP: ...!uunet!motcid!henley /
/__________________________________________________________________/

steve@groucho.ucar.edu (Steve Emmerson) (05/10/90)

jmm@eci386.uucp (John Macdonald) writes:

>Try the following instead:

>    #ifdef DEBUG_PRINT_ON
>    #   define DEBUG printf
>    #else
>    #   define DEBUG(ignore)
>    #endif

>To insert a DEBUG-conditional printf use:

>    DEBUG( "format", args, ... );

>(no double parens or other funny syntax required, it just looks like
>a function call)

Be aware that some C compilers will have problems with the above due to
an "argument mismatch" between the usage of the macro and its definition.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

guy@auspex.auspex.com (Guy Harris) (05/10/90)

>Isn't the use of __LINE__ non-portable?

The use of __LINE__ is portable to all ANSI C implementations, and to
many non-ANSI C implementations (including most, if not all, UNIX ones).