c语言中宏定义的一个问题

c语言中宏定义的一个问题

晚风撩人 发布于 2021-11-26 字数 410 浏览 786 回复 26

最近看RTT源码时看到一个宏定义是这样定义的

#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) func argv; } while (0)

定义了一个钩子函数,我知道这个宏定义是调用func函数指针,argv是参数,但总感觉哪里不太对。各位有对宏定义这部分的资料吗?我对这里总是不太清楚

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(26

甜柠檬 2021-12-01 26 楼




反话 2021-12-01 25 楼

你好,我不知道怎么回复你时上传图片,所以我把图片传到评论栏闲了。你可以看一下。实际上这个函数指针只是定义了但没有赋值,所以宏中argv是NULL的,后面的不会执行。但我认为既然他这样写了,如果定义了话也必然可以的

醉生梦死 2021-12-01 24 楼

回复
从你的代码里面,看到有一个RT_USING_HOOK必须要定义,你这段代码才会生效,你确定这个宏真的存在吗??我怎么看这段代码都是语法错误。

后知后觉 2021-12-01 23 楼

谢谢你帮我回答这个问题,上面有一楼的兄弟解释了,我看明白了。,你可以看一下。再次感谢

坐在坟头思考人生 2021-12-01 22 楼

回复
我去,没注意看argv的使用,居然把括号放在使用的时候加!!够奇葩。。

三月梨花 2021-12-01 21 楼

呵呵,我原来也是没注意看,所以直接蒙圈了。

像你 2021-12-01 20 楼

LZ确定你的代码能编译通过吗?如果能通过,请把你使用RT_OBJECT_HOOK_CALL的相关代码贴出来一下,比如func和argv的声明与定义。

只看你这个定义,先不说你完成啥功能,单从参数的名字上来理解,这段代码应该有语法错误吧??

柳若烟 2021-12-01 19 楼

如果是为了动态参数,其实使用__VA_ARGS__应该会更好一点,当然这样也是没错,只是看上去好奇怪,而且使用感觉也不方便,就算没有参数,第二个也需要一个空的()。

复古式 2021-12-01 18 楼

这里宏定义argv为什么没加(),是因为这个括号一定在调这个宏的地方加,里面是直接展开的,所以这个时候就完全和参数数目无关了。

筱果果 2021-12-01 17 楼

如果是函数指针,那你需在func前加上“*”。

#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) *(func)(argv); } while (0)

冷清清 2021-12-01 16 楼

是这样的,我看其中调用时传入的func是函数指针,不过我写了函数测试时发现传入函数指针编译过不去

裸钻 2021-12-01 15 楼

func是函数的话,那它后面须加括号。

#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) (func)(argv); } while (0)

命硬 2021-12-01 14 楼

你这样说就没意思了,我只不过是想搞明白怎么回事罢了,不是来唬你的

能否归途做我良人 2021-12-01 13 楼

回复
你需要把相关代码也贴出来。单纯的 if (... func argv; 这样的写法好吗?哈。

岁月打碎记忆 2021-12-01 12 楼

这样写的代码,也是醉了。哈。别拿代码出处来“唬”我。这种写法并不好。。你至少argv是可变参吧。

嘦怹 2021-12-01 11 楼

是这样的,调用时传入的func是函数指针,argv是变量,但我自己写函数测试时不管传入的是函数指针还是函数编译都过不去,如果func后面加括号编译运行都可以。我的疑问是为什么argv外面没有加括号?

睫毛上残留的泪 2021-12-01 10 楼

func是函数,不是函数指针。这个是宏展开,所以调用的时候,把对应的字符串什么的都展开即可。

情绪失控 2021-12-01 9 楼

是这样的,楼主连问题都没有说出,自己把编译时的汇编输出一下,都清楚了。

苍暮颜 2021-12-01 8 楼

是这样的,调用时传入的func是函数指针,argv是变量,但我自己写函数测试时不管传入的是函数指针还是函数编译都过不去,如果func后面加括号编译运行都可以。我的疑问是为什么argv外面没有加括号

平定天下 2021-12-01 7 楼

回复
写宏一定要加括号,哪怕是
#define f(x) x * x也要写成#define f(x) ((x) * (x)),因为编译器是提前用 ((x) * (x)) 替换代码中的任何 f(x) 这样的字符文本,然后才去转化成机器码。

孤檠 2021-12-01 6 楼

回复
你这代码应该改为 #define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) (func(argv)); } while (0)

柠檬 2021-12-01 5 楼

宏是字符文本替换,跟函数调用是两码事

成熟稳重的好男人 2021-12-01 4 楼

没有的,所以我不太明白

女中豪杰 2021-12-01 3 楼

argv前后少括号吧

一个人的旅程 2021-11-29 2 楼

嗯,谢谢啊,我看明白了。麻烦你了

眼眸里的那抹悲凉 2021-11-26 1 楼

晕了,回复得在200个字以内,单独回吧:

你可以在代码中搜索哪些地方调用过,例如ipc.c中的调用:
RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(sem->parent.parent)));

连起来就是:
do {
  if (rt_object_trytake_hook != RT_NULL)
    rt_object_trytake_hook(&(sem->parent.parent));
} while (0);

func确实是函数指针,这个我说错了。