c - 使用 ## 运算符扩展宏

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

s1 是一个简单的数组,s2 是一个有 4 个 vector 作为成员的结构

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 VAR(name, num) name##num
int VAR(foo, 1);  // foo and 1 must be pasted together as foo1, instead of foo 1

宏应该编译并修复几个语法错误和丢失的声明

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

注意一个compound statement { ... } 不是表达式,不能这样使用。通过在其周围添加额外的括号,您正在使用 gnu's extension并且不是标准 C。

相反,您应该编写一个函数来执行此操作。然后您将能够返回 _x 并且使用现代优化器,应该可以忽略不计的开销。

关于c - 使用 ## 运算符扩展宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47206932/

相关文章:

arrays - 剖析这段代码,解释 - 检查数组是否是另一个数组的子集

c - C中的假匿名函数

scala - 如何键入检查 Def Def

variables - 将符号解析为宏与函数参数的规则是什么?

c - 为什么将这些宏函数转换为函数不能正常工作?

位扩展/复制算法?

c - 如何在我的 minishell 中处理 null 环境变量?

c - 在 C 中打开二进制文件

c++ - Windows C - 通过引用将指针传递给使用 MIDL 协议(protocol)的 unsigned char 的动态分配内存

c - 如何使用 C 将所有内容从我的终端复制到一个文件,包括标准输出和提示符?