Are preprocessor directives allowed in a function-like macro's argument?

This question regards the legality of using a preprocessor directive within a function-like macro’s argument.

Consider the following code. #ifdef is used inside MY_MACRO‘s argument :

#include <iostream>

// Macro to print a message along with the line number the macro appears at
#define MY_MACRO( msg ) { std::cerr << "Line " << __LINE__ << "\t- "<< msg << '\n'; }

int main()
{
    // Print the current build configuration
    MY_MACRO(
#ifdef NDEBUG // <-- preprocessor directive in macro argument
        "Release"
#else
        "Debug"
#endif
    )
}

gcc 12 is fine with it, msvc 19 does not allow it : https://godbolt.org/z/G8j4aTG6j

What does the standard have to say about it?

>Solution :

Short answer: No

[cpp.replace.general]:

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.

Leave a Reply