I'm trying to make macro-like function that will "create" few lines of new macros. ARM-GCC preprocessor is not happy with that macro-like function. Any ideas how to achieve same functionality without extern tools?
#define SML_DEBUG(_name) \
#if defined(DEBUG_##_name) \
#define _name##_LOG DEBUG_HANDLER \
#else \
#define _name##_LOG(...) \
#endif
Task is to create macros for functions for printing debug stuff.
Eg.,
#define DEBUG
#define DEBUG_HANDLER log
#define DEBUG_TEST // Enable debug prints for test module
#define SML_DEBUG(TEST) // Should create test_LOG macro or its placeholder if DEBUG build is disabled
void foo(void)
{
TEST_LOG("Hello World\n"); // Will redirect to "log" function(defined by DEBUG_HANDLER)
}
Error is:
error: '#' is not followed by a macro parameter
182 | #define SML_DEBUG(_name) \
| ^
Thanks!
The specific error you are getting is because #
in a function-like macro (not a macro-like function) is supposed to be used as the stringizing operator, as in #define MakeString(x) #x
, per C 2018 6.10.3.2 1. Since you have #if
, and if
is not a parameter name, the compiler complains. (That is a constraint paragraph, so the compiler is required to complain about it.)
Even if #
were allowed in a macro replacement list, the source code resulting from processing a macro is not processed as a preprocessor directive (such as #if
, #else
, and #endif
) even if it resembles one, per C 2018 6.10.3.4 3.
Instead of attempting to define a macro with conditional source code, you can conditionally define a macro:
#if defined DEBUG_TEST
#define _TEST_LOG DEBUG_HANDLER
#else
#define _TEST_LOG(...)
#endif
That means you would need to repeat those lines for each module you want to enable/disable logging for, but that is what source code editors and scripting languages are for. Not everything should be done in the C preprocessor.