1

Hello I am trying to Make A Macro that gets a parameter and tries to add postFix to it.

#define myPostFix HelloWorld
#define macro(x) x ##myPostFix 
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)

Expected behavior is to get

CAlgThreadHandleObjectHelloWorld

What I actually get is:

CAlgThreadHandleObjectmyPostFix 

Can Some1 help me to get the expected behavior please? Please note that myPostFix is something I have to define in project GCC definitions and it should vary from project to project.

3 Answers 3

1

Try:

#define myPostFix HelloWorld
#define macro_2(x, y) x##y
#define macro_1(x, y) macro_2(x, y)
#define macro(x) macro_1(x, myPostFix)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)

You need the intermediate macro_1 to let the preprocessor substitute myPostFix assignement, then macro_2 to concatenate strings. This solution let you assign myPostFix to the value you want.

To clarify how preprocessor and symbol replacement works consider that the preprocessing translation phase is not recursive on parameters, so the translation need to pass through a forced parameter expansion more than one time up to expand all parameters.
In our case:

  1. CAlgThreadHandleObject expands to : macro(CAlgThreadHandleObject)
  2. macro(CAlgThreadHandleObject) expands to : macro_1(CAlgThreadHandleObject, myPostFix)
  3. macro_1 expands to: macro_2(CAlgThreadHandleObject, HelloWorld)
  4. And last macro_2 expands to: CAlgThreadHandleObjectHelloWorld
Sign up to request clarification or add additional context in comments.

3 Comments

Note that the name _macro is reserved by the compiler, since it starts with an underscore, you should avoid it if possible.
@DietrichEpp Yes you're right. Under strict Ansi words beginning with underscore are reserved for for compiler extensions. I'll fix it. Thanks
Thanks for clarification on preprocessing expansions.
1

You actually need to go three layers deep with this one in order to get the macro to expand properly. I can't pretend to understand the exact reasoning why this is necessary (not that I want to understand...)

#define MY_ADDPOSTFIX3(x, y) x ## y
#define MY_ADDPOSTFIX2(x, y) MY_ADDPOSTFIX3(x, y)
#define MY_ADDPOSTFIX(x) MY_ADDPOSTFIX2(x, MY_POSTFIX)

MY_ADDPOSTFIX(Func)

You can test this:

$ gcc -E test.c -DMY_POSTFIX=HelloWorld
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"




FuncHelloWorld

And...

$ gcc -E test.c -DMY_POSTFIX=Goodbye | tail -n 1
FuncGoodbye

2 Comments

Thank you sir, it worked :) However I would like to know the reason why so :)
@user3351949: That would be an excellent question on its own. I, however, do not share your sentiment. I already know too much about the C preprocessor and wish I knew less.
1

Simply pass it through another call of the macro macro so the define is expanded. I slightly changed the macros, but the functionality is the same:

#define myPostFix HelloWorld
#define macro2(x,y) x##y
#define macro(x,y) macro2(x,y)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject,myPostFix)

1 Comment

Thank you sir it worked like a charm! Could you explain the reason that I have to pass it twice?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.