[comp.lang.c] How can I use #define to make something completely disappear?

wayne@ames.arpa (10/31/87)

Time for my dumb question of the month ...

I have the following sequence many times in a piece of code:

        #ifdef DEBUG
            printf("XYZ entry, p1=%x, p2=%x\n", p1, p2);
        #endif DEBUG

Normal old obvious stuff, right?  What I would like to do is replace
all of these sequences with something like:

            DBPRINT("XYZ entry, p1=%x, p2=%x\n", p1, p2);

and then have one instance of something like:

        #ifdef DEBUG
        #define DBPRINT printf
        #else
        #define DBPRINT

But of course that doesn't make it; leaving the compiler with

        ("XYZ entry, p1=%x, p2=%x\n", p1, p2);

won't help anything!  For the above example I could of course say

        #ifdef DEBUG
        #define DBPRINT(a,b,c) printf(a,b,c)
        #else
        #define DBPRINT(a,b,c)

but that only works when there are exactly three arguments, and
obviously printf's can have more or less than that.  Guess I could
define DBPRINT1, DBPRINT2, DBPRINT3, etc., but that sounds less than
aesthetic.

Anybody got any suggestions?  (Sure hope this is another one of those
"Boy, that sure is easy; why are you bothering the net?" type things!)

      Wayne Hathaway                  ultra!wayne@Ames.ARPA
      Ultra Network Technologies
      2140 Bering drive               with a domain server:
      San Jose, CA 95131                 wayne@Ultra.COM
      408-922-0100

 

ljz@fxgrp.UUCP (10/31/87)

In article <10083@brl-adm.ARPA> ultra!wayne@ames.arpa (Wayne Hathaway) writes:
>
>Anybody got any suggestions? [ about how to conditionally comment out printf]

How 'bout ...

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

Then, in your program you can have ...

        D(printf("%s %s %d %d %g\n", foo, bar, baz, furd, farkle));

The double parens are a bit unaesthetic to me, but this gets the job done.

Another variation ...

#ifdef DEBUG
# define dprintf(X)	printf X
#else
# define dprintf(X)
#endif

Then, in your program ...

	dprintf(("%s %s %d %d %g\n", foo, bar, baz, furd, farkle));

More double parens, but it works.

You can get fancy with if statements, testing of debug flags, etc., but I
think you get the idea.

-- 
Lloyd Zusman, Master Byte Software, Los Gatos, California
"We take things well in hand."
...!ames!fxgrp!ljz

edw@IUS1.CS.CMU.EDU.UUCP (10/31/87)

In article <10083@brl-adm.ARPA>, ultra!wayne@ames.arpa (Wayne Hathaway) writes:
  [A lot of stuff about how do I write a macro that allows the option to
   include or not to include code depending on whether a switch is defined]

  Heres what I do:

#ifdef DEBUG

#define if_debug(x)	x

#else

#define if_debug(x)

#endif


	if_debug( printf("XYZ entry, p1=%x, p2=%x\n", p1, p2) );


 BTW:  Are the macros __FILE__ and __LINE__ define for all C compilers??

-- 

					Eddie Wyatt

e-mail: edw@ius1.cs.cmu.edu

chris@mimsy.UUCP (Chris Torek) (11/01/87)

In article <850@tut.cis.ohio-state.edu> lvc@tut.cis.ohio-state.edu
(Lawrence V. Cipriani) writes:
>... I also added a command line option, say -d, so that even if DEBUG
>was defined you needed -d to get the printfs. ...
>
>#define DBPRINT(arglist) if (dflag != 0) printf arglist

I suggest instead

#define	DBPRINT(arglist) if (dflag == 0) /* void */; else printf arglist

so that you can use, e.g.,

	if (it was minor)
		DBPRINT((...));
	else
		abort(...);

without having the `else' wind in up the wrong place.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

allan@didsgn.UUCP (allan) (11/02/87)

In article <10083@brl-adm.ARPA>, ultra!wayne@ames.arpa (Wayne Hathaway) writes:
>                                   What I would like to do is replace
> all of these sequences with something like:
> 
>             DBPRINT("XYZ entry, p1=%x, p2=%x\n", p1, p2);
> 

One thing that I have used in various C programs is the following:

	#ifdef DO_DEBUG
	#define DEBUG(x) x
	#else
	#define DEBUG(x)
	#endif

then use the debugging lines as follows:

	if ( overt_error )
	{
		DEBUG(printf("Danger Will Robinson! %d %d %d\n", 1,2,3)) ;
		do_recovery() ;
	}

or whatever form you need. The only drawback from this form is that the 
"DEBUG" statement must be on only one line as it is the preprocessor that
does this work and macros must be contained on one line (or should I say
"logical" line?). The above form is also nice as programs can be compiled
in "DEBUG" mode from the command line.
For example:
	cc myprog -DDO_DEBUG

Also, this will work with "if"s as the semi-colon is outside of the DEBUG macro.

Thus,
	if ( d_flag )
		DEBUG(printf("Doing debug stuff\n"));
	else
	    printf("It works!");

works.

I hope this is helpful for you.

-Allan G. Schrum

usenet: ..!gatech!rebel!didsgn!allan

rlk@chinet.UUCP (Richard Klappal) (11/04/87)

In article <10083@brl-adm.ARPA> ultra!wayne@ames.arpa (Wayne Hathaway) writes:
>Time for my dumb question of the month ...
>I have the following sequence many times in a piece of code:
>        #ifdef DEBUG
>            printf("XYZ entry, p1=%x, p2=%x\n", p1, p2);
>        #endif DEBUG
>Normal old obvious stuff, right?  What I would like to do is replace
>all of these sequences with something like:
>
>            DBPRINT("XYZ entry, p1=%x, p2=%x\n", p1, p2);
>
>and then have one instance of something like:
>
>        #ifdef DEBUG
>        #define DBPRINT printf
>        #else
>        #define DBPRINT
>

Two ways I can think of:
	1) Check back a couple of weeks in the sources archives for
	Fred Fish's DBUG package.  It does exactly what you want, plus
	a whole lot more.

	2) When you edit the file to change the printf(...) to
	DBPRINT(...)  make it as follows:

#ifdef DEBUG
#define DBPRINT(args) printf args
#else
#define DBPRINT(args)
#endif

main()
{
	DBPRINT((x, y, z));
}


cc -E ... produces:

	# 1 "def.c"
	# 3 "def.c"

	main()
	{
		;
	}


cc -DDEBUG -E ... produces

	# 1 "def.c"

	# 5 "def.c"

	main()
	{
		printf (x, y, z);
	}

The extra set of parens does it.  This is adapted from Fred's
technique, to give credit where its due.  Thanks Fred.
-- 
---
UUCP: ..!ihnp4!chinet!uklpl!rlk || MCIMail: rklappal || Compuserve: 74106,1021
      ..!ihnp4!ihu1h!rlk
---

garys@bunker.UUCP (Gary M. Samuelson) (11/05/87)

In article <9187@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>I suggest instead
>
>#define	DBPRINT(arglist) if (dflag == 0) /* void */; else printf arglist

>so that you can use, e.g.,

>	if (it was minor)
>		DBPRINT((...));
>	else
>		abort(...);
>
>without having the `else' wind in up the wrong place.

Other possible ways to avoid 'else' problems:

	if (it was minor)
	{
		DBPRINT((...));
	}
	else
	{
		abort(...);
	}

I often surround 'then' and 'else' statements with braces, even if
there is only one statement there.  BUT I do not want to start more
discussions on the use or non-use of braces.  I already know how to
use them the *right* way. :-)

Instead, I offer yet another debug macro:

#define	DBPRINT(arglist) {if (dflag) printf arglist;}

Now there will be no problem with else's.
Note that this one should be invoked without a trailing semicolon:
	DBPRINT((...))

Or:

#define DBPRINT(arglist) (dflag ? printf arglist : 0 )

Gary Samuelson

msb@sq.UUCP (11/06/87)

Chris Torek (chris@mimsy.UUCP) suggests:

> #define DBPRINT(arglist) if (dflag == 0) /* void */; else printf arglist

As he says, this form lets the macro work correctly inside if-statements.

Personally, though, I prefer to make my macros expression-like no matter
how complicated it makes them; then I know that what looks like an
expression statement really is an expression statement, and again they
work anywhere.

The above can in fact be written about
as simply in expression style, as either of:

#define DBPRINT(arglist) (dflag && printf arglist)
#define DBPRINT(arglist) (dflag? printf arglist: 0)

or other stylistic variations that I don't need to enumerate (and neither
do you, probably).

Of the three forms in this message, I strongly prefer the last, as it is
the only one that expresses the ifness in the conventional sense (as it
would normally be said outside a macro in C).

				"Avoid null THEN" -- Kernighan and Plauger
Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb, msb@sq.com

wcs@ho95e.ATT.COM (Bill.Stewart) (11/09/87)

> DEBUGPRINT( "format %s", arg1, arg2, ...);
A crude approach is
	#ifdef DEBUG
	#define DEBUGPRINT printf
	#else
	#define DEBUGPRINTF (void)
	#endif
This will always evaluate the argument list, which is undesirable if
some of the arguments have side-effects (e.g. i++ ).
An alternative is to use
	#define DEBUGPRINTF 0 &&
which should short-circuit evaluation of the ( .. , .. ) list.
(Lint may not give you any respect, but...).
-- 
#				Thanks;
# Bill Stewart, AT&T Bell Labs 2G218, Holmdel NJ 1-201-949-0705 ihnp4!ho95c!wcs

TGMIKEY%CALSTATE.BITNET@wiscvm.wisc.EDU (Account Manager) (11/13/87)

Received: by CALSTATE via BITNet with NJF for TGMIKEY@CALSTATE;
Comment: 10 Nov 87 05:05:16 PST
Received: by BYUADMIN (Mailer X1.24) id 3809; Tue, 10 Nov 87 06:04:44 MST
Date:     31 Oct 87 12:30:44 GMT
Reply-To: Info-C@BRL.ARPA
Sender:   INFO-C@NDSUVM1
From:     ljz@fxgrp.uucp
Subject:  Re: How can I use #define to make something completely disappear?
Comments: To: info-c@brl-smoke.arpa
To:       TGMIKEY@CCS.CSUSCC.CALSTATE.EDU

In article <10083@brl-adm.ARPA> ultra!wayne@ames.arpa (Wayne Hathaway) writes:
>
>Anybody got any suggestions? [ about how to conditionally comment out printf]

How 'bout ...

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

Then, in your program you can have ...

        D(printf("%s %s %d %d %g\n", foo, bar, baz, furd, farkle));

The double parens are a bit unaesthetic to me, but this gets the job done.

Another variation ...

#ifdef DEBUG
# define dprintf(X)    printf X
#else
# define dprintf(X)
#endif

Then, in your program ...

    dprintf(("%s %s %d %d %g\n", foo, bar, baz, furd, farkle));

More double parens, but it works.

You can get fancy with if statements, testing of debug flags, etc., but I
think you get the idea.

--
Lloyd Zusman, Master Byte Software, Los Gatos, California
"We take things well in hand."
..!ames!fxgrp!ljz

===== Reply from Mike Khosraviani <TGMIKEY> ==========================

We are trying to get rid of paranthesis (C is not considered an artificial
language program yet)  LISP uses them enought, thank you!!!!

If you wonder if I have any better suggestions or NOT, the answer is NOT!!!!
So, I guess we have to put up with those ('s.


Mike