We have a function macro #define FOO(arg) foo(arg)
with int foo(const char* bar);
. When NDEBUG is defined FOO is defined as #define FOO(arg) 0
, however this causes many compiler warnings because in many cases FOO's return value is not used. The solution should work with with ANSI C compilers and cause no warnings. I've tried:
(void)0
: can't be assigend to variable
static int foo(const char* bar) { return 0; }
: causes unused static function warning in some modules
static inline int foo(const char* bar) { return 0; }
: only works with C99 compilers
Thanks for your help!
edit1:
It's somewhat like a trace macro and used all over the project. Mostly it's just used as a statement like FOO("function x called");
, but in a few cases I saw if (FOO("condition a")) { /* some more debug output */ }
. With NDEBUG defined and optimization enabled nothing should be left of FOO. I didn't come up with this, but I have to clean up this mess :).
edit2: I should add that for gcc release builds these flags are used: -O3 -Wall -ansi
edit3: For now I'm going with __inline int dummy() { return 0; }
. __inline works with both VisualC and GCC in ansi mode.
I guess it's a little bit compiler dependent but this should work:
#ifndef NDEBUG
#define FOO(arg) foo(arg)
#else
#define FOO(arg) ((int)0)
#endif
It prevents the "expression has no effect" warning, it does nothing and its value when used is still 0.
EDITED
It seems it's something not so portable so (now) you have these conditions:
(0)
or ((int)0)
work at least on VC 2010.__noop
should work on any version of VC after 2003.VC6 is not a problem because it doesn't emit the C4555 warning at all. For other compilers you may use:
((void)0, 0)
It may work on a lot of compilers (maybe it's the more portable one?).inline int foo(const char* bar) { return 0; }
works with any other C99 compiler (as you wrote you may need to declare it as static
on gcc).For any other prehistoric C compiler use the solution pointed by @Jobs: abs(0)
What you could do to prevent the warning is the following:
#ifndef NDEBUG
#define FOO(arg) foo(arg)
#else
#define FOO(arg) abs(0)
#endif
I'm not saying this is ideal (you'd have to make sure stdlib.h
is included everywhere, for example) but it does prevent the warning.
I'd do something that is dependent on the C version. In the header file:
#if __STDC_VERSION__ > 199900L
inline int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif
in one compilation unit
#if __STDC_VERSION__ < 199900L
int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif
or use for the oldish C version something like Job's answer, that is a function that is certain to be optimized out but that doesn't produce the warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With