用于传递多个变量参数的C宏

时间:2017-11-12 10:20:56

标签: c

我有一个函数将参数作为数组。我还给出了具有匿名数组初始化的数组值,例如

        myfunction(char[]{1,1,1,0},int[]{2,2,0});

myfunction扫描每个数组直到找到零元素。当你将零放到数组的末尾时,可以接受不同大小的数组。

我需要一个C宏来包装myfunction。

        #define WRAP_MY_FUNCTION(X,Y)  myfunction(int[]X,char[]Y)

并希望使用如下:

       WRAP_MY_FUNCTION({1,1,1,0},{2,2,0}) 

获取我的功能:

       myfunction(char[]{1,1,1,0},int[]{2,2,0})

但是编译器说你输入7个参数但是预期有2个参数。 然后我尝试了如下的可变参数:

       #define WRAP_MY_FUNCTION(...)  myfunction(int[]__VA_ARGS__,char[]__VAR_ARGS__) 

但正如上面在此方法中所见,不可能为每个数组初始化创建不同的 VA_ARGS 表达式。

是否可以用C宏使用实现这样的实现?

注意:我在这个宏用法中的主要用途是匿名数组初始化,我不想定义结构,如int x [4] = {1,1,1,0};从我的问题中可以看出int y [3] = {2,2,0} ...等。 我希望写下面的宏

              WRAP_MY_FUNCTION({1,1,1,0},{2,2,0})

M Oehm和Florian Weimer感谢您的回答。它们是可以接受的,但是现在我也愿意听取新的答案。特别是如所提到的M Oehm,我的目标是在数组的末尾隐藏0。

3 个答案:

答案 0 :(得分:2)

尝试 - #define WRAP_MY_FUNCTION(x,y)(myfunction(x,y))

并按如下方式调用define:

WRAP_MY_FUNCTION(X,Y);

其中x是:int x [] = {1,1,1,0};

和y是:char y [] = {2,2,0};

答案 1 :(得分:2)

宏参数中的逗号被视为宏参数分隔符,除非它们嵌套在括号中。像这样的东西会起作用:

void my_function(int[], char[]);
#define WRAP_MY_FUNCTION(x, y) my_function((int[]) x, (char[]) y)
#define ARG(...) { __VA_ARGS__ }

WRAP_MY_FUNCTION(ARG(1, 2, 3), ARG(4, 5, 6));

似乎没有办法摆脱额外的宏调用,因为

(int[]) ({1, 2, 3})

在语法上没有效果(并且它已被重用为GNU扩展),并且

(int[]) {(1, 2, 3)}

具有不同的含义,因为它调用逗号运算符并创建一个元素数组。

答案 2 :(得分:2)

预处理器无法检测参数中的花括号,但它可以检测嵌套括号。将您的宏重新设计为:

WRAPPER((1, 1, 1), (2, 2, 0));

以下定义:

#define IARG(...) int[]{__VA_ARGS__, 0}
#define CARG(...) char[]{__VA_ARGS__, 0}
#define WRAPPER(CHARS, INTS) funct(CARG CHARS, IARG INTS)
然后

将扩展为:

funct(char[]{1, 1, 1, 0}, int[]{2, 2, 0, 0});

宏调用中的括号将被视为CARGIARG的参数。替代过程是:

WRAPPER((1, 1, 1), (2, 2, 0));
funct(CARG (1, 1, 1), IARG (2, 2, 0));
funct(char[]{1, 1, 1, 0}, int[]{2, 2, 0, 0});
但是,我不确定那个宏是否能为你买得多。嵌套的括号语法不直观,您可能最好使用逐字语法,尤其是几个月后重新访问代码时。 (我已经让宏自动终止了数组,因此至少某些有利于使用它。)