Stopping macro expansion

c, c-preprocessor

Solution

It requires you to have at least a C99 compiler, since C99 allows empty macro arguments. However some compilers may allow them as an extension, even in C89 mode. Here is the code:

#include <stdio.h>

#define CONST_ABC 15
#define CONST_5 7
#define ABC 5

#define PRINT(x) printf("CONST=%d\n", CONST_ ## x)

// The problematic macro
#define PRINT2(x, y) PRINT(x ## y)

int main(int argc, char *argv[])
{
    PRINT(ABC); // Prints 15 - OK
    PRINT2(ABC,); // Prints 7 - Not OK.
}

The second argument (i.e. the `y`) is empty, making it an empty preprocessing token. The `##` operator prevents argument expansion, so the result of the concatenation is the same as `x` argument.

C11 6.10.3.1/p1 Argument substitution (emphasis mine):

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a `#` or `##` preprocessing token or followed by a `##` preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

Problem

I have a problem with macro expansion deferral. Here is an example: ``` #include <stdio.h> #define CONST_ABC 15 #define CONST_5 7 #define ABC 5 #define PRINT(x) printf("CONST=%d\n", CONST_ ## x) // The problematic macro #define PRINT2(x) PRINT(x) int main(int argc, char *argv[]) { PRINT(ABC); // Prints 15 - OK PRINT2(ABC); // Prints 7 - Not OK. } ``` How to define `PRINT2` macro so that it will use `PRINT` and result would be 15? I'm getting: ``` CONST=15 CONST=7 ``` And want to get: ``` CONST=15 CONST=15 ```

Original source

Related problems