使用#和##运算符嵌套的宏实现

时间:2019-06-03 11:42:48

标签: c macros

我正在编写一个通用函数,它将使用宏名称并执行正确的函数。

我正在编写一个将从宏中获取函数名称并连接并执行该函数的函数。我在工作空间中添加了此头文件,其中多个c文件使用此宏实现逻辑来执行我的代码。运行代码时出现错误。

#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);

预期结果:如果取消注释主语句中实际宏语句的上面的行并注释当前的宏语句,则可以运行代码。但是我想让我的代码以当前逻辑运行。

1 个答案:

答案 0 :(得分:4)

当替换宏时,C首先用其参数替换每个参数。因此,例如将参数c替换为VAL_F。然后,它应用##运算符,在此示例中将生成convert_fVAL_FDATA_SIGNVAL_NUM。然后,C检查结果以查找要替换的其他宏。但是,此时,VAL_F之类的参数已与##合并为单个标记,并且不再是将被替换的单个标记。

要解决此问题,请使用一个宏替换参数,然后使用另一个宏应用##运算符。更改:

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

收件人:

#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)