You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

带函数参数的宏:实现调用传入的无参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

火山引擎 最新活动