I have the following code
#define LogError(...) fprintf(stderr, __VA_ARGS__)
And I want another marco to print error log only in debug mode, so I expect that, with
#define DebugLogError(...) \
#ifndef NDEBUG \
fprintf(stderr, __VA_ARGS__); \
#endif
code DebugLogError("hello %s", "world")
to expand to
#ifndef NDEBUG
fprintf(stderr, "hello %s", "world") \
#endif
But the code is not compiling.
How can this be implemented?
>Solution :
The C standard does not provide features for using preprocessor statements inside macros. Instead of trying use a #if inside a macro, use the #if to control how you define the macro:
#if defined NDEBUG
// If NDBUG is defined, define the macro to be replaced by nothing.
#define DebugLogError(...)
#else
// Otherwise, define the macro to print a debugging message.
#define DebugLogError(...) fprintf(stderr, __VA_ARGS__);
#endif
However, it is often preferable to modify the macro so it can be used like a function call followed by a ;, fitting more smoothly into the C grammar:
#if defined NDEBUG
// If NDBUG is defined, define the macro to be replaced by nothing.
#define DebugLogError(...) \
do { } while (0)
#else
// Otherwise, define the macro to print a debugging message.
#define DebugLogError(...) \
do fprintf(stderr, __VA_ARGS__); while (0)
#endif
Defining them in the latter form will avoid errors where an extra semicolon (in the no-NDEBUG case) or missing code (in the NDEBUG case) would cause problems, like:
if (SomeCondition)
DebugLogError(stuff);
else
OtherCode;