宏调用函数

时间:2017-03-07 17:47:17

标签: c macros arguments c-preprocessor preprocessor

我需要一个宏(或一个函数,但最好是一个宏),它接受一个函数名和一个无限数量的参数,然后将参数传递给函数。我们假设这个宏是MACROFOO

#define MACROFOO(function, ...)     /* what do I put here?? */

int foo_bar(int x, int y)
{
    // do stuff
}

int main(void)
{
    int x = 3;
    int y = 5;

    MACROFOO(foo_bar, x, y);    // calls foo_bar(x, y)
}

我怎么能定义这样的宏?我想做类似的事情:

#define MACROFOO(function, args...)     (function)(args)

但它似乎将...传递给函数,而不是实际的参数。我该怎么办?

2 个答案:

答案 0 :(得分:6)

您可以使用...展开可变参数宏的__VA_ARGS__

示例:

#define MACROFOO(function, ...)  (function)(__VA_ARGS__)

MACROFOO(printf, "hello world%c", '!') 
/*^ expands to: (printf)("hello world%c", '!') */

注意:您可能知道,括号会阻止function参数作为宏扩展(如果它是宏)。

即,

#define BAR(...) myprintf(__VA_ARGS__)
MACROFOO(BAR, "hello world%c", '!')

将扩展为:

(BAR)("hello world%c", '!')

括号和

myprintf("hello world%c", '!')

如果你删除它们。

答案 1 :(得分:5)

您可以使用标准变量参数__VA_ARGS__

#define MACROFOO(function, ...)  (function)(__VA_ARGS__)

或者如果您喜欢更具描述性的名称,可以在...之前写一个名称来使用此GNU CPP扩展名:

#define MACROFOO(function, parameters...)  (function)(parameters)

GNU CPP Section 3.6:

  

(...)    Variadic宏是C99中的新功能。 GNU CPP支持他们   很长一段时间,但只有一个命名变量参数('args ...',   不是'...'和__VA_ARGS __)。

     

如果您担心可移植性   在以前的GCC版本中,您应该只使用命名变量   参数。另一方面,如果你担心可移植性   其他符合C99的实现,你应该只使用   __VA_ARGS __。