c语言中宏定义的一个问题
最近看RTT源码时看到一个宏定义是这样定义的
#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) func argv; } while (0)
定义了一个钩子函数,我知道这个宏定义是调用func函数指针,argv是参数,但总感觉哪里不太对。各位有对宏定义这部分的资料吗?我对这里总是不太清楚
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(26)
你好,我不知道怎么回复你时上传图片,所以我把图片传到评论栏闲了。你可以看一下。实际上这个函数指针只是定义了但没有赋值,所以宏中argv是NULL的,后面的不会执行。但我认为既然他这样写了,如果定义了话也必然可以的
谢谢你帮我回答这个问题,上面有一楼的兄弟解释了,我看明白了。,你可以看一下。再次感谢
回复
从你的代码里面,看到有一个RT_USING_HOOK必须要定义,你这段代码才会生效,你确定这个宏真的存在吗??我怎么看这段代码都是语法错误。
回复
我去,没注意看argv的使用,居然把括号放在使用的时候加!!够奇葩。。
如果是为了动态参数,其实使用__VA_ARGS__应该会更好一点,当然这样也是没错,只是看上去好奇怪,而且使用感觉也不方便,就算没有参数,第二个也需要一个空的()。
LZ确定你的代码能编译通过吗?如果能通过,请把你使用RT_OBJECT_HOOK_CALL的相关代码贴出来一下,比如func和argv的声明与定义。
只看你这个定义,先不说你完成啥功能,单从参数的名字上来理解,这段代码应该有语法错误吧??
呵呵,我原来也是没注意看,所以直接蒙圈了。
这里宏定义argv为什么没加(),是因为这个括号一定在调这个宏的地方加,里面是直接展开的,所以这个时候就完全和参数数目无关了。
如果是函数指针,那你需在func前加上“*”。
#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) *(func)(argv); } while (0)
是这样的,我看其中调用时传入的func是函数指针,不过我写了函数测试时发现传入函数指针编译过不去
func是函数的话,那它后面须加括号。
#define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) (func)(argv); } while (0)
这样写的代码,也是醉了。哈。别拿代码出处来“唬”我。这种写法并不好。。你至少argv是可变参吧。
回复
你需要把相关代码也贴出来。单纯的 if (... func argv; 这样的写法好吗?哈。
你这样说就没意思了,我只不过是想搞明白怎么回事罢了,不是来唬你的
是这样的,调用时传入的func是函数指针,argv是变量,但我自己写函数测试时不管传入的是函数指针还是函数编译都过不去,如果func后面加括号编译运行都可以。我的疑问是为什么argv外面没有加括号?
func是函数,不是函数指针。这个是宏展开,所以调用的时候,把对应的字符串什么的都展开即可。
是这样的,楼主连问题都没有说出,自己把编译时的汇编输出一下,都清楚了。
是这样的,调用时传入的func是函数指针,argv是变量,但我自己写函数测试时不管传入的是函数指针还是函数编译都过不去,如果func后面加括号编译运行都可以。我的疑问是为什么argv外面没有加括号
回复
写宏一定要加括号,哪怕是
#define f(x) x * x也要写成#define f(x) ((x) * (x)),因为编译器是提前用 ((x) * (x)) 替换代码中的任何 f(x) 这样的字符文本,然后才去转化成机器码。
回复
你这代码应该改为 #define RT_OBJECT_HOOK_CALL(func, argv) do { if ((func) != RT_NULL) (func(argv)); } while (0)
宏是字符文本替换,跟函数调用是两码事
没有的,所以我不太明白
argv前后少括号吧
嗯,谢谢啊,我看明白了。麻烦你了
晕了,回复得在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确实是函数指针,这个我说错了。