cc-preprocessor

Macro-like function with macros inside the body


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!


Solution

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