Page 1 of 2
#define blah #ifdef -help! (C not C++)
Posted: Sun Jul 09, 2006 3:29 pm
by earlz
I am attempting to make some debugging macros because I hate having to type #ifdef DEBUG it takes so long to type and it is not very pretty so I tried making some macros like this:
Code: Select all
//these just make it tons easier
#define DEBUG_ON #ifdef DEBUG
#define DEBUG_OFF #endif
//prints only if debugging
#define DBPRINT(string) \
#ifdef DEBUG \
printf("debug: ");\
printf(string);\
#endif
//end dbprint
I get # is not followed by a macro paremeter
and ifdef not declared and syntax error at #
so is this possible or do I have to do it the extremely ugly way
Re:#define blah #ifdef -help! (C not C++)
Posted: Sun Jul 09, 2006 5:40 pm
by Kemp
Think of this logically. Say you have:
Code: Select all
#define DEBUG_ON #ifdef DEBUG
DEBUG_ON
The pre-processor will run through it and the replace it to:
Which will then be sent to the compiler, which has no concept of what any of that means as it's not C code.
It's not that hard to use this:
Code: Select all
#define DBPRINT(string) \
printf("debug: ");\
printf(string);
and then in the code:
Code: Select all
#ifdef DEBUG
DBPRINT("foobar")
#endif
Re:#define blah #ifdef -help! (C not C++)
Posted: Sun Jul 09, 2006 6:44 pm
by earlz
well the debug_on and off is my main thing I wanted
but for dbprint I figured why not do it like assert and the macro be blank if debug is not defined
Re:#define blah #ifdef -help! (C not C++)
Posted: Sun Jul 09, 2006 7:18 pm
by Kemp
The basic problem is that afaik you can't use pre-processor directives within pre-processor directives because it only does one pass, so the ones you're swapping the text to are passed to the compiler, which says "wtf?
" and falls over.
Re:#define blah #ifdef -help! (C not C++)
Posted: Sun Jul 09, 2006 10:51 pm
by Solar
Jordan3 wrote:
#define DEBUG_ON #ifdef DEBUG
#define DEBUG_OFF #endif
Use [tt]#define DEBUG[/tt] or [tt]gcc -DDEBUG[/tt] instead. Kemp is right, you cannot "nest" preprocessor directives like that. Use [tt]gcc -E[/tt] to find out what your preprocessor does with your code here.
While you're at it, use NDEBUG instead of DEBUG - that way you can toggle assert() and your DBPRINT() with the same flag.
Re:#define blah #ifdef -help! (C not C++)
Posted: Mon Jul 10, 2006 10:21 am
by Candy
you could also change the logic:
Code: Select all
#ifdef DEBUG
#define DEBUG_ON if(1) {
#define DEBUG_OFF }
#else
#define DEBUG_ON if(0) {
#define DEBUG_OFF }
#endif
// note, you can use semicolons but you normally shouldn't.
DEBUG_ON
printf("some debug thingy");
DEBUG_OFF
Or, what I might like more (not sure yet):
Code: Select all
#ifdef DEBUG
#define debug if(1)
#else
#define debug if(0)
#endif
// logical statement rather than plain defines
// needs people to know what debug does though.
debug {
printf("some debug thingy");
}
Re:#define blah #ifdef -help! (C not C++)
Posted: Mon Jul 10, 2006 1:59 pm
by earlz
Thanks so much!
I think i like the last method or well probably have both methods though
Re:#define blah #ifdef -help! (C not C++)
Posted: Tue Jul 11, 2006 10:55 am
by mystran
Alternatively you can have static inline functions like this
Code: Select all
#ifdef DEBUG
static inline void debug(char * x) {printk(x);}
#else
static inline void debug(char * x) {}
#endif
I like Candy's [tt]debug { ... }[/tt] syntax though, because it allows arbitary statements, and creates a new local scope for temporaries. Often figuring out the data-to-be-printed is more work than actually printing it.
The [tt]DEBUG_ON[/tt] / [tt]DEBUG_OFF[/tt] is IMHO worse because it too creates a scope without the [tt]{}[/tt] that would normally tell you there's one.
Re:#define blah #ifdef -help! (C not C++)
Posted: Tue Jul 11, 2006 1:10 pm
by Candy
mystran wrote:
I like Candy's [tt]debug { ... }[/tt] syntax though, because it allows arbitary statements, and creates a new local scope for temporaries. Often figuring out the data-to-be-printed is more work than actually printing it.
I'm liking it more & more too, it's in a way very clear about what it's doing (most people would claim you're modifying the language, it fits in that well) and it does exactly what you'd want it to do (so even if you don't know it, you can use it). This one's a keeper for me.
Re:#define blah #ifdef -help! (C not C++)
Posted: Tue Jul 11, 2006 3:02 pm
by earlz
another thing is you can use the else command wiht it for releases
like this
Code: Select all
debug{
printf("This is a debug version...\n");
}else{
printf("This is a release version...\n");
}
though it might cause some confusion
Re:#define blah #ifdef -help! (C not C++)
Posted: Thu Aug 17, 2006 3:04 am
by Pype.Clicker
Jordan3 wrote:
though it might cause some confusion
i'd mostly fear that it become tempting to have real code in the "else { ... }" part, and that the "debugging" version differs not only by the verbosity level, but also by the nitty-gritty details of its implementation.
Re:#define blah #ifdef -help! (C not C++)
Posted: Thu Aug 17, 2006 5:42 am
by df
in my debugging system I have two parts.
Code: Select all
void _LogWrite(char *strFile, long lineno, char *strX, ...)
{
#ifndef NLOGWRITE
va_list args;
va_start(args, strX);
vsprintf(strLogBuffer, strX, args);
printf("%s(%li) : %s", strFile, lineno, strLogBuffer);
va_end(args);
fflush(stderr);
#endif
}
and a macro
Code: Select all
#define LogWrite(...) _LogWrite(__FILE__, __LINE__, __VA_ARGS__)
and I define NLOGWRITE in gcc if I need it.. gcc -DNLOGWRITE etc...
I also have another routine for the same thing which you pass a severity flag with it and it will only print logging messages over a certain level.. (user controlled. good for testing....)
so in my code I just use
Code: Select all
LogWrite("blah blah %i value of 0x%08lX", a, b);
Re:#define blah #ifdef -help! (C not C++)
Posted: Thu Aug 17, 2006 5:54 am
by Solar
One hint on that: Make sure your compiler is smart enough to optimize the call to _LogWrite() away to nothing when NLOGWRITE is defined, or be aware that even with logging disabled you're paying for a function call whenever _LogWrite() comes up.
This can get really nasty when you're applying this to C++ code, where converting a complex object to string (to satisfy operator<<() ) can get really expensive.
Re:#define blah #ifdef -help! (C not C++)
Posted: Thu Aug 17, 2006 7:29 am
by df
thats ok, I only write C not c++ so its safe
plus it never goes away as I use a VerbsoseWrite(level, .....) so I am always using it in some capacity..
thats not to say it couldnt be improved in several ways
Re:#define blah #ifdef -help! (C not C++)
Posted: Thu Aug 17, 2006 11:12 am
by JoeKayzA
Solar wrote:
This can get really nasty when you're applying this to C++ code, where converting a complex object to string (to satisfy operator<<() ) can get really expensive.
A bit OT, just out of interest: Do you know whether there is a good or common solution against this problem?
cheers Joe