Search code examples
cmacrosconcatenation

Concatenating macro name before expansion


Let's say I have two macro definitions:

#define TEST 0
#define TEST_NAME "Joe"

I'd like to create a macro that can get access to the second definition from the first.

I tried the following

#define ID_TO_NAME(id) id ## _NAME
printf("%s\n", ID_TO_NAME(TEST));

However this doesn't work because the result is 0_NAME instead of TEST_NAME. Is there a way to concatenate the tokens before the macro expansion occurs?


Solution

  • Your code can be reduced to (in order to understand what happened only):

    #define TEST 0
    #define TEST_NAME "Joe"
    #define ID_TO_NAME(id) id ## _NAME
    ID_TO_NAME(TEST)
    

    ## is the concatenation operator in Preprocessor which paste 2 tokens to form another valid token. The problem is one of the tokens is an argument parameter.

    From GNU C Preprocessor documentation (3.5):

    If either of the tokens next to an ‘##’ is a parameter name, it is replaced by its actual argument before ‘##’ executes. As with stringification, the actual argument is not macro-expanded first. If the argument is empty, that ‘##’ has no effect.

    What happens to ID_TO_NAME(TEST)? :

    1. So first it will be generated to TEST_NAME creating a valid token.
    2. After that the CPP will do a macro expansion to TEST_NAME which becomes "joe".

    So the normal result would be "joe" based on the input of your question.

    In your case you said it was 0_NAME the only reason would be:

    • There was an expansion of argument TEST before being concatenated which requires some definitions of macros and which you did not mention.

    Or

    • There was a redefinition of an object-like macro TEST_NAME to 0_NAME before the invocation.

    What I suggest is: check your code again or reformulate your question.