使用##运算符扩展宏

P.C*_*ino 4 c macros expansion

大家好,问题是我在这个宏中

 #define ADD_COMP(s1,s2,type)({\
  int _x=0;\
  for(int i=0;i<n_addrs;i++){\
    if(memcmp(s1,&(s2->##type),6)!=0){\
      _x=-1;\
    }else{\
      break;\
    }\
  }\
  _x;\
})
Run Code Online (Sandbox Code Playgroud)

s1是一个简单的数组,s2是一个结构,有4个向量作为这样的成员

typedef struct example{
 char[6] one,
 char[6] two,
 char[6] three
}example;
Run Code Online (Sandbox Code Playgroud)

现在由于自己的原因,我需要创建一个函数,将大小为6字节的s1数组与仅仅示例的成员进行比较,因此为此我使用##运算符编写ADD_CMP以使其更通用所以我定义了:

#define one
#define two
#define three
Run Code Online (Sandbox Code Playgroud)

我以这种方式使用函数不同时间希望宏扩展的成功

ADD_COMP(some_array,example1,one)
ADD_COMP(some_array,example1,two)
ADD_COMP(some_array,example1,three)
Run Code Online (Sandbox Code Playgroud)

但编译器返回错误:

error: pasting "->" and "one" does not give a valid preprocessing token
error: pasting "->" and "two" does not give a valid preprocessing token
error: pasting "->" and "three" does not give a valid preprocessing token
Run Code Online (Sandbox Code Playgroud)

如何在不为每个结构成员编写相同功能的情况下修复它?

Pas*_* By 5

正如错误所暗示的那样,从来没有必要##,因为它用于粘贴两个预处理标记以形成单个标记.

#define VAR(name, num) name##num
int VAR(foo, 1);  // foo and 1 must be pasted together as foo1, instead of foo 1
Run Code Online (Sandbox Code Playgroud)

宏应编译修复几个语法错误和缺少声明

 #include<stdlib.h>
 #include<string.h>

 int n_addrs = 6;

 #define ADD_COMP(s1,s2,type) {\
  int _x=0;\
  for(int i=0;i<n_addrs;i++){\
    if(memcmp(s1,&(s2->type),6)!=0){\
      _x=-1;\
    }else{\
      break;\
    }\
  }\
  _x;\
}

typedef struct example{
 char one[6];
 char two[6];
 char three[6];
}example;

void foo(void)
{
    example* example1 = malloc(sizeof(example));
    char some_array[6];
    ADD_COMP(some_array,example1,one)
    ADD_COMP(some_array,example1,two)
    ADD_COMP(some_array,example1,three)
}
Run Code Online (Sandbox Code Playgroud)

请注意,复合语句 { ... }不是表达式,因此不能使用.通过在其周围添加额外的括号,您使用gnu的扩展名并且不是标准C.

你应该改为编写一个函数来代替.然后,您将能够返回_x并使用现代优化器,对于不存在的开销应该可以忽略不计.