By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,003 Members | 1,171 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,003 IT Pros & Developers. It's quick & easy.

Question about #define

P: n/a
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
Nov 14 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
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

"Jorge Naxus" <eg*******@terra.es> wrote in message
news:dc**************************@posting.google.c om...
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

Nov 14 '05 #2

P: n/a
On 1 Mar 2004 07:10:01 -0800, eg*******@terra.es (Jorge Naxus) wrote:
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
le**@bdsoft.com
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
Nov 14 '05 #3

P: n/a
Jorge Naxus wrote:

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.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #4

P: n/a
news:dc**************************@posting.google.c om...
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.
Nov 14 '05 #5

P: n/a
In article <40***********************@news.versatel.net>,
"Frank van Eijkelenburg" <so*****@work.com> wrote:
#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
Nov 14 '05 #6

P: n/a
In article <dc**************************@posting.google.com >,
Jorge Naxus <eg*******@terra.es> wrote:
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
Nov 14 '05 #7

P: n/a
John Cochran <jd*@smof.fiawol.org> wrote:
#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.

--
Stan Tobias
Nov 14 '05 #8

P: n/a
In article <c2*************@ID-223330.news.uni-berlin.de>,
Stan Tobias <sN*******@amu.edu.pl> wrote:
John Cochran <jd*@smof.fiawol.org> wrote:
#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.


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.

Nov 14 '05 #9

P: n/a
> 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.
Nov 14 '05 #10

P: n/a

On Mon, 1 Mar 2004, Old Wolf wrote:
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


....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

Nov 14 '05 #11

P: n/a
On 1 Mar 2004 07:10:01 -0800, eg*******@terra.es (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
Nov 14 '05 #12

P: n/a

In article <84**************************@posting.google.com >, ol*****@inspire.net.nz (Old Wolf) writes:
I would like to write a macro like that:

#ifdef DEBUG


#define printj printf
#else


#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.


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)?

--
Michael Wojcik mi************@microfocus.com

Even though there may be some misguided critics of what we're trying
to do, I think we're on the wrong path. -- Reagan
Nov 14 '05 #13

P: n/a
In article <84**************************@posting.google.com >,
Old Wolf <ol*****@inspire.net.nz> wrote:
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.


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__));

Nov 14 '05 #14

P: n/a
Jorge <te***@egrojorge.es> wrote:
# On 1 Mar 2004 07:10:01 -0800, eg*******@terra.es (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.

--
Derk Gwen http://derkgwen.250free.com/html/index.html
Raining down sulphur is like an endurance trial, man. Genocide is the
most exhausting activity one can engage in. Next to soccer.
Nov 14 '05 #15

P: n/a

On Wed, 3 Mar 2004, Derk Gwen wrote:

Jorge <te***@egrojorge.es> wrote:
# On 1 Mar 2004 07:10:01 -0800, eg*******@terra.es (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
Nov 14 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.