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.