Search code examples
c++macrospreprocessorpreprocessor-meta-program

Macro expansion problems in MSVC


I wonder why this macro is expanding so much.

#define CONCAT_IMPL(A, B) A##B
#define CONCAT(A, B) CONCAT_IMPL(A, B)

#define EAT(...)
#define TEST(ARG) EXPANDED, ARG) EAT(
#define GET_LAST(A, B) B

int result = 0;
result = GET_LAST(CONCAT(TEST, (1)), 2); // result is 2
result = GET_LAST(TEST(1), 2); // result is 2
result = GET_LAST(EXPANDED, 1) EAT(, 2); // result is 1

I want GET_LAST(CONCAT(TEST, (1)), 2); evaluated value 1.

I'd appreciate it if you could tell me if it's possible on MSVC or if something's missing.


Solution

  • C11 draft:

    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.

    GET_LAST(CONCAT(TEST, (1)), 2) is an invocation of the macro GET_LAST with a list of two arguments. One is CONCAT(TEST, (1)) and the other one is 2.

    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.

    The first parameter A does not occur in the replacement list of the macro, so nothing is done with the corresponding argument. The second parameter B occurs, so the corresponding argument macro-expands to 2, and the occurrence of B in the replacement list is substituted with the expansion.