关于 C 的函数指针指向任意函数类型

2019-06-17 19:34:55 +08:00
 haozhang

如果我想要表达一个指向任意函数类型的函数指针的话,用:

typedef void (*Function)(void);
Function f = ...;

还是使用:

typedef void *(*Function)(void *);
Function f = ...;

又或者用别的什么方式呢?

3695 次点击
所在节点    C
29 条回复
letianqiu
2019-06-18 09:05:47 +08:00
@wutiantong 你仔细去看我给出的链接里的例子。C++里将一个函数赋值给 void *类型的指针的结果是为定义的。楼下已经有人提到了,void *只能表示数据类的指针
zwhfly
2019-06-18 09:20:35 +08:00
各位,void * 类型是不能存储函数指针的。

https://stackoverflow.com/questions/5579835/c-function-pointer-casting-to-void-pointer

只谈 C。
按 C 标准,函数指针可以转换为另一种类型的函数指针,但调用时必须转换到原类型使用。C 标准不支持函数指针与 void 指针互转。
虽说现实中的大多数编译器支持与 void 指针互转,但这么写是不符合标准的,是不好的。

回答题主的问题,答案是两种都可以,但第二种没必要,第一种比较干净一点。
nanmian
2019-06-18 09:40:13 +08:00
1.void* 能不能存函数指针不知道....
2.单纯提个疑问,调用时的输入输出规则你怎么约定了?

这样堆栈很容易不平衡的导致程序崩溃的。我曾经在 VS2015_C 语言_Win32 Console_Debug 上测试过,把一种函数指针强转为另外一种指针然后传值调用,如果默认约定是调用者平衡堆栈还好,只是输入输出会取错值(若涉及写形式参数的话,还可能出现"越界访问"),程序不会崩溃。但如果是被调用者平衡堆栈的话,程序会因为堆栈平衡性检查出错而崩溃。
wutiantong
2019-06-18 10:34:50 +08:00
@letianqiu 是我 sb 了,其实我昨天打开你那个链接加载得太慢一直没出来页面内位置,然后从上往下翻到了一处讲 pointer to member function 能不能转 void *的,就以为是你给的地方。关于能不能转我好像也搞错了,不好意思哈。
haozhang
2019-06-18 12:41:35 +08:00
结贴,最终我使用了:typedef void (*Function )(void);Function f = ...;
haozhang
2019-06-18 12:43:34 +08:00
@nanmian 你强制类型转了之后,调用的时候还是要转换为原来函数的类型啊,不然肯定会出错的。
12tall
2019-06-18 17:06:25 +08:00
void * 可以指向任意数据,但是在使用时一般需要类型转换成相应的类型才可以
haozhang
2019-06-18 20:31:34 +08:00
@12tall 回顾下上面的回复,void *无法指向函数指针的。
12tall
2019-06-19 11:25:53 +08:00
@haozhang 谢谢提醒!
感觉 http://www.c-faq.com/ptrs/generic.html 这个回复更让人信服,不能保证正确的转换;
StackOverflow 里面的情况感觉和 void * 关系不大。因为之前在调单片机中断时就遇到了有时候需要必要的延时(任意一条语句)才能正确执行,和这个问题很像(跑题了似乎

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/574837

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX