Question about #define

J

Jorge Naxus

Hello

I would like to write a macro like that:

#ifdef DEBUG
#define printj(...) printf(...)
#else
#printj(...)
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false.
But I dont know how to deal with the variable number of arguments of
printf(...).

Any help on how should be my "define"??

Thanks,

Jorge
 
F

Frank van Eijkelenburg

You can use:

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

but now you should use printj as: printj(("just a test\n"));

AFAIK macros don't support a variable number of arguments.

Frank
 
L

Leor Zolman

Hello

I would like to write a macro like that:

#ifdef DEBUG
#define printj(...) printf(...)
#else
#printj(...)
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false.
But I dont know how to deal with the variable number of arguments of
printf(...).

Any help on how should be my "define"??

C99 does (as I just discovered to my complete surprise by Googling)
support variadic macros! So if you're coding in C99 you're all set.

Otherwise, I'd probably approach this by creating an ordinary (non-macro)
variadic printj function inside of which, via conditional compilation
(based presumably on your DEBUG symbol), either hands off to a
printf-family function (e.g. vprintf) or doesn't.
-leor
Thanks,

Jorge

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
C

CBFalconer

Jorge said:
I would like to write a macro like that:

#ifdef DEBUG
#define printj(...) printf(...)
#else
#printj(...)
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false. But I dont know how to
deal with the variable number of arguments of printf(...).

Any help on how should be my "define"??

You have two choices.

1. Get and use a C99 compiler. Then your code will no longer port
to a C90 compiler.

2. Get and use gcc and the gnu variadic macro extensions. Then
your code will no longer port to a non-gnu compiler. If you get a
late enough gcc you can combine with option 1, because the latest
gccs handle C99 variadic macros in addition to the gnu flavor.

The only example I can show you is in nmalloc.zip, available on my
page, download section. It is using exactly those facilities, and
is thus limited to gcc compilation.
 
M

Mark Henning

Hello

I would like to write a macro like that:

#ifdef DEBUG
#define printj(...) printf(...)
#else
#printj(...)
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false.
But I dont know how to deal with the variable number of arguments of
printf(...).

Any help on how should be my "define"??

Thanks,

Jorge

I normally end up creating about 5 seporate macros for the task.

#ifdef DEBUGMODE
#define DEBUG_PRINT(a) printf(a)
#define DEBUG_PRINT1(a,b) printf(a,b)

etc, etc..

inelegant, but it works fine for me.
 
F

Francois Grieu

"Frank van Eijkelenburg said:
#ifdef DEBUG
#define printj(x) printf((x))
#else
#define printj(x)
#endif

but now you should use printj as: printj(("just a test\n"));

probably Frank meant:

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

but now you should use printj as:
printj(("just a test\n"));
printj(("%d %d %d\n",1,2,3));

and must NOT use
printj(("%d\n",++j));

[not tested]

François Grieu
 
J

John Cochran

Hello

I would like to write a macro like that:

#ifdef DEBUG
#define printj(...) printf(...)
#else
#printj(...)
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false.
But I dont know how to deal with the variable number of arguments of
printf(...).

Any help on how should be my "define"??

Thanks,

Jorge

I see two possible solutions.
1. If you are using a C99 compatable compiler, then what you want is

#ifdef DEBUG
#define printj(...) printf(__VA_ARGS__)
#else
#define printj(...) ((void)0)
#endif

2. If you are using a C89 compatable compiler, then the following will work.


#ifdef DEBUG
#define printj printf
#else
#define printj (void)
#endif


The 2nd method requires a little bit of explaining and has some drawbacks.
When DEBUG is defined, I believe that you'll see that it does what you want.
If DEBUG isn't defined, what you'll see is that you get a series of comma
seperated expressions inside parens and the final result of these expressions
is then cast to void. This behaivor is also what you want. The drawback
is that the printj macro isn't a function-like macro and therefore everywhere
the compiler sees printj, it will make the subsitution. For example, look
at the following code:

int main(void)
{
int printj;

for(printj=0; printj < 10; ++printj) {
printf("%d\n", printj);
}
return 0;
}

The above example is perfectly legal using the macros for C99, but will fail
to compile using the macros for C89.

Hope this helps,
John Cochran
 
S

Stan Tobias

John Cochran said:
#ifdef DEBUG
#define printj printf
#else
#define printj (void)
#endif

The 2nd method requires a little bit of explaining and has some drawbacks.
When DEBUG is defined, I believe that you'll see that it does what you want.
If DEBUG isn't defined, what you'll see is that you get a series of comma
seperated expressions inside parens and the final result of these expressions
is then cast to void. This behaivor is also what you want. The drawback

One other drawback is that all sub-expressions within the comma-expression
are evaluated, all side-effects apply, and that might not be what
you want.
 
J

John Cochran

One other drawback is that all sub-expressions within the comma-expression
are evaluated, all side-effects apply, and that might not be what
you want.

True, but if you have side effects in your debug statements, then something
is seriously wrong with your code and/or design because you will get different
results from your code depending on if debug is enabled or not.
 
O

Old Wolf

I would like to write a macro like that:
#ifdef DEBUG
#define printj(...) printf(...)

#define printj printf
#else
#printj(...)

#define printj
#endif

So that printj behaves exactly like printf when DEBUG is true and
doesnt do anything when DEBUG is false.

NB. Avoid using printj's return value

NB2. You say "doesnt do anything". All the solutions offered so far
do evaluate printj's arguments (eg. if you went: printj("%d", foo());
then foo gets called). To prevent this you will have to use the
normal method of #ifdef etc. around each printf.
 
A

Arthur J. O'Dwyer

#define printj printf


#define printj


NB. Avoid using printj's return value

....because in reality 'printj' doesn't have a return value; it has
a textual expansion whose type at compile-time depends on the value
of DEBUG. If (DEBUG != 0), then sure, you can use the return value
of 'printj' (a.k.a. 'printf'). If (DEBUG == 0), then you have to
jump through many more hoops to get any useful information out of
that comma expression you've [presumably] got there.
NB2. You say "doesnt do anything". All the solutions offered so far
do evaluate printj's arguments (eg. if you went: printj("%d", foo());
then foo gets called). To prevent this you will have to use the
normal method of #ifdef etc. around each printf.

No, there are a couple of hacks for this situation. One silly
and not-quite-foolproof one is

#ifndef DEBUG
#define printj (int)sizeof
#endif

This fails in the (hopefully unlikely) case of

printj("foo")[i++];

which should increment 'i', but with the current definition actually
does not. (Note that I've chosen to make 'printj' evaluate to type
'int', so that its type doesn't change when 'DEBUG' changes. That's
a style issue, I'm sure, and in real code I probably wouldn't even
do it.)

I was trying to compose a solution that would involve stringizing
the 'printj' "argument," but that really doesn't seem possible
(as long as we must keep the semantics that 'printj' be a drop-in
replacement for 'printf' in ordinary code).

-Arthur
 
J

Jorge

On 1 Mar 2004 07:10:01 -0800, (e-mail address removed) (Jorge Naxus) wrote:

Thanks to all the people who has helped me on these question, I have
learned a lot.

I dont have a C99 compiler (I am cross compiling), so I have used the
method proposed by John Cochran

#ifdef DEBUG
#define printj printf
#else
#define printj (void)
#endif

Although other possibilities you have pointed out would also be valid.

Acttually I dont change anything in my printf statements because these
are only for debugging purposes, so I dont mind if there are evaluated
or not.

I hate to read the C sources plenty of #ifdef around if statement, so
I think my code will be more beautiful now


Thanks!,

Jorge
 
M

Michael Wojcik

#define printj printf


#define printj


NB. Avoid using printj's return value

NB2. You say "doesnt do anything". All the solutions offered so far
do evaluate printj's arguments (eg. if you went: printj("%d", foo());
then foo gets called). To prevent this you will have to use the
normal method of #ifdef etc. around each printf.

I'd never use something like this, but how about one of:

#define printj 0 &&
#define printj 1 ||

for the non-DEBUG case, as a solution that doesn't evaluate the
arguments for subexpressions (not necessarily what's wanted, of
course) and evaluates to a known value (so the "return value"
is usable).

Or am I missing some obvious case where this construct fails
(as well as being ugly and obscuring the code, of course)?
 
L

Lawrence V. Cipriani

#define printj printf


#define printj


NB. Avoid using printj's return value

NB2. You say "doesnt do anything". All the solutions offered so far
do evaluate printj's arguments (eg. if you went: printj("%d", foo());
then foo gets called). To prevent this you will have to use the
normal method of #ifdef etc. around each printf.

I've used this for more years than I care to admit:

#ifdef DEBUG
#define PRINT(arglist) fprintf arglist
#else
#define PRINT(arglist)
#endif

and then use it like:

PRINT((stderr, "foobar: %d\n", __LINE__));
 
D

Derk Gwen

# On 1 Mar 2004 07:10:01 -0800, (e-mail address removed) (Jorge Naxus) wrote:
#
# Thanks to all the people who has helped me on these question, I have
# learned a lot.
#
# I dont have a C99 compiler (I am cross compiling), so I have used the
# method proposed by John Cochran
#
# #ifdef DEBUG
# #define printj printf
# #else
# #define printj (void)
# #endif
#
# Although other possibilities you have pointed out would also be valid.

If printj is only used as statement you can use
#define printj if(0)

If the argument list side effect free, many compilers and any optimising
compiler will recognise the code is dead and elide it.
 
A

Arthur J. O'Dwyer

# On 1 Mar 2004 07:10:01 -0800, (e-mail address removed) (Jorge Naxus) wrote:
#
# Thanks to all the people who has helped me on these question, I have
# learned a lot.
#
# I dont have a C99 compiler (I am cross compiling), so I have used the
# method proposed by John Cochran
#
# #ifdef DEBUG
# #define printj printf
# #else
# #define printj (void)
# #endif
#
# Although other possibilities you have pointed out would also be valid.

If printj is only used as statement you can use
#define printj if(0)


if (somecondition)
printj("somecondition checks out\n");
else
printj("somecondition is false; or else it isn't, and !DEBUG\n");

Whoops! Better you should have said "If printj is only used inside
{ }, or in harmless situations...", and that's a lot harder to get
right.

-Arthur
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,815
Members
47,361
Latest member
RogerDuabe

Latest Threads

Top