0

Here is the code.

#include <iostream>
using namespace std;

#define gao falsegao
#define fun(entity) \
    void fun_##entity() \
    {                     \
        std::cout << #entity << std::endl; \
    }

fun(gao);

int main()
{
    fun_gao();
    return 0;
}

This program will compile and run at ease. But why? I have already defined gao as falsegao, shouldn't the generated function be void fun_false_gao()? And the output should be false_gao, too.

Please help me solve this puzzle, when will the substitution take place ? what's the principle behind this?

richard.g
  • 3,585
  • 4
  • 16
  • 26

2 Answers2

1

You need a two-leveled fun macro

#define fun_(entity) \
    void fun_##entity() \
    {                     \
        std::cout << #entity << std::endl; \
    }

#define fun(entity) fun_(entity) 

That will work as intended.

Rules of macro substitution of C++ language prevent preprocessor from recursively replacing macro names in tokens adjacent to ## or # operators. You need an additional level of "isolation" to make sure that gao gets replaced with falsegao before it gets to ## or #.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

No, the ## operator has higher precedence than parameter substitution. Idiomatically it's wrapped inside a macro:

#define CAT_LITERAL( A, B ) A ## B
#define CAT( A, B ) CAT_LITERAL( A, B )

The same applies to the # operator.

#define STR_LITERAL( LIT ) # LIT
#define STR( PARAM ) STR_LITERAL( PARAM )

So your macro is defined:

#define fun(entity) \
    void CAT( fun_, entity ) () \
    {                     \
        std::cout << STR( entity ) << std::endl; \
    }
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421