带函数参数的宏:实现调用传入的无参void函数
搞定APPLY_FUNCTION宏的定义问题
嘿,这个问题我之前写C代码时也踩过类似的坑,咱们一步步来解决它~
首先得搞明白你原来的宏为啥不工作:你写的#define APPLY_FUNCTION(function) (function),当调用APPLY_FUNCTION(function);时,预处理器会把它展开成(function);——这只是把函数名用括号包了起来,本质上就是个函数指针的表达式,根本没触发函数调用啊!要让函数跑起来,必须加上调用用的()才行。
正确的宏定义写法
最简单的正确写法就是给宏里的函数加上调用括号:
#define APPLY_FUNCTION(function) (function())
要是想更严谨,避免一些语法陷阱(比如宏跟着if语句不加括号时出问题),可以用C里常用的do-while(0)封装技巧:
#define APPLY_FUNCTION(function) do { (function)(); } while(0)
为啥用do-while(0)?举个例子,如果你写:
if (flag) APPLY_FUNCTION(my_func);
如果用简单的(function())版本,展开后是if (flag) (my_func());,这没问题,但要是宏里有多条语句,就会出语法错误。而do-while(0)能让宏的行为完全像一个普通函数调用,不管放在什么场景下都不会翻车。
测试一下效果
比如你有这个测试函数:
void function(void) { printf("函数执行啦!\n"); }
用正确的宏调用:
APPLY_FUNCTION(function);
不管用哪个版本的宏,展开后都会正确执行function(),输出对应的内容。
额外提醒
- 要保证传入宏的确实是无参数的void类型函数,要是传了带参数的函数,编译器会直接报错,这正好符合你的需求。
- 给宏参数加上括号(比如
(function))是个好习惯,能避免运算符优先级带来的意外问题,这也是上面两个版本都加括号的原因。
内容的提问来源于stack exchange,提问作者John Trend




