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

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

s1是一个简单的数组,s2是一个包含4个向量的结构,其成员如下
typedef struct example{
 char[6] one,
 char[6] two,
 char[6] three
}example;

现在出于自身原因,我需要创建一个函数,将大小为6字节的s1数组与示例中的一个成员进行比较,因此为此,我使用运算符编写了add_cmp,使其尽可能更通用
所以我定义:
#define one
#define two
#define three

我以这种方式多次使用这个函数希望宏扩展成功
ADD_COMP(some_array,example1,one)
ADD_COMP(some_array,example1,two)
ADD_COMP(some_array,example1,three)

但是编译器返回错误:
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

如果不为每个结构成员编写相同的函数,如何修复它?

最佳答案

令牌粘贴运算符是为希望将两个不同的预处理器令牌粘附到单个令牌中的情况而设计的。例如,你可以写一些

#define Glue(x) x my##x_

然后写
Glue(int);

要获取此变量声明:
int my_int;

在这里,标记粘贴将标记“my_”与标记“int”结合起来,形成新的标记“my_int”,这是一个表示名称的新的单个标记。
一旦将两个令牌粘贴在一起,预处理器就不会重新扫描它们,以确定它是否是几个不同的单个令牌的组合。它把形成的东西当作一个单一的标记。例如,此代码不会编译:
#define BadAdd(x, y) x##+##y
int z = BadAdd(137, 42);

这里的问题是,标记粘贴形成一个预处理标记137+42。然后,预处理器尝试将此预处理令牌映射到单个逻辑令牌,但没有对应的单个令牌。通常,C或C++将此视为三个独立的令牌(137、+和42),但是既然强制将它们粘合在一起,编译器就不知道它在看什么。
与此相对应的是更传统的add宏,为了便于说明,它省略了大量重要的括号:
#define Add(x, y) x + y
int z = Add(137, 42);

这里,add(137,42)扩展成一个由三个标记(137,+,42)组成的序列,编译器在后面的阶段可以将其解释为加法表达式。
上面编写的宏类似于badadd宏。通过将->标记与字段名粘在一起,您将得到一个编译器无法有意义地解释为单个标记的单个单元,如->one。只需删除这里的-就像从badadd到add一样,这将生成一系列标记,而不是一个单独的标记,这正是您想要的。

09-12 12:24