user3476225
user3476225

Reputation: 240

nested macro implementation with # and ## operator

I am writing a generic function which will take macro name and execute correct function.

I am writing a function which will take function name from macro and concatenate this and execute the function.I am adding this header file in my workspace where more than one c file use this macro implementation logic to execute my code.But I am getting error while running the code .

#define STR(name) #name

int convert_f14u18(int a,int b);
int convert_f14s18(int a,int b);

#define VAL_F 14
#define DATA_SIGN u
#define VAL_NUM 18

#define EXECUTE_FUN_NAME(a,b,c,d,e)  a##b##c##d##e
#define EXECUTE_STATEMENT(a,b,c,d,e,f)  b##c##d##e#f=EXECUTE_FUN_NAME(a,b,c,d,e)

typedef int u32;
u32 add_u32(u32 a,u32 b);

int main() {

    //Testing of string macro
    printf(STR(Hello));

    int numa = 10;
    int numb = 20;
    int numc = 30;


    //int z1 = EXECUTE_FUN_NAME(convert_,f,14,u,18)(numa,numb);
    int z1 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numb);

    //int z2 = EXECUTE_FUN_NAME(convert_,f,14,s,18)(numa,numc);
    int z2 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numc);


    printf("\nz1 %d\n",z1);
    printf("z2 %d\n",z2);


    return 0;
}


int convert_f14u18(int a,int b){
    return (a+b);
}
int convert_f14s18(int a,int b){
    return (a+b);
}

u32 add_u32(u32 a,u32 b){
    return (a+b);
}
Error:../main.cpp: In function ‘int main()’:
../main.cpp:37:76: error: ‘convert_fVAL_FDATA_SIGNVAL_NUM’ was not  declared in this scope
 int z1 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numb);

Expected result: If I un-comment the lines above of actual macro statement in main statements and comment the current macro statements, I am able to run the code. But I want to make my code run with the current logic .

Upvotes: 0

Views: 61

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 224310

When replacing a macro, C first replaces each parameter with its argument. So the argument c is replaced with VAL_F, for example. Then it applies the ## operator, which produces convert_fVAL_FDATA_SIGNVAL_NUM in this example. Then C checks the result for additional macros to substitute. However, at that point, the arguments, such as VAL_F, have been made into a single token with ## and are no longer individual tokens that will be replaced.

To deal with this, use one macro to replace the arguments, then use another macro to apply the ## operator. Change:

#define EXECUTE_FUN_NAME(a,b,c,d,e)  a##b##c##d##e

to:

#define EXECUTE_FUN_NAME_HELPER(a, b, c, d, e)  a##b##c##d##e
#define EXECUTE_FUN_NAME(a, b, c, d, e)         EXECUTE_FUN_NAME_HELPER(a, b, c, d, e)

Upvotes: 4

Related Questions