我试图将一个整数转换为函数指针。基本上我的整数值包含函数指针的地址,所以我试图把它转换成它。
我正在尝试执行以下操作 -
typedef void (*func_ptr)(unsigned int arg1);
void function1(unsigned int argument)
{
}
void function2(unsigned int argument, func_ptr argument2)
{
/* Do something here*/
}
void function3(unsigned int argument)
{
function2(123,(func_ptr)argument);
}
我正在调用function3,其参数包含function1的地址。当我运行程序时,我收到以下警告 -
cast to pointer from integer of different size [-Wint-to-pointer-cast]
我有什么方法可以处理这个警告吗?
答案 0 :(得分:3)
将整数转换为函数指针
“我希望让它与系统无关”
这不是100%可能,因为C没有指定一个可以保存所有orignal 函数指针的整数类型。
整数可以转换为任何指针类型。除非先前指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。 C11dr§6.3.2.3 5
走另一条路:
任何指针类型都可以转换为整数类型。除了之前指定的以外,结果是实现定义的。 如果结果无法以整数类型表示,则行为未定义。结果不必位于任何整数类型的值范围内。 §6.3.2.3 6
示例:函数指针为128位,最宽整数类型为64位。
代码可以尝试使用最宽的整数类型,如(u)intmax_t
。虽然这确实很有成功的机会,但在某些平台上它仍然可能太小。
可选的整数类型(如(u)intptr_t
)可以往返void *
对象指针。 函数指针可能比void *
宽,因此这种方法不足以用于独立于系统的解决方案。
答案 1 :(得分:2)
不要养成尝试将整数类型转换为指针的习惯。这不是传递某事物地址的正确方法 - 这就是为什么存在指针类型的原因。 (是的,你可以用无符号类型表示一个指针,条件是无符号类型与指针大小相同,但不要使用指针需要指针)
在function3
的示例中,您要从其中调用function2
。由于function2
需要将func_ptr
类型作为参数,function3
的参数列表中应该包含func_ptr
类型的参数,以便您可以将其传递给function2
内。 (除非你在全局范围内定义了func_ptr
- 但除非绝对需要,否则应该避免 - 例如回调,这里不相关,在学习C时很少见到)
将您的作品组合在一起的简短示例可能有所帮助。这样可以使用函数定义和typedef为function3
提供适当的参数,它可以在调用function2
时使用它,例如
#include <stdio.h>
typedef void (*func_ptr)(unsigned int arg1);
void function1(unsigned int argument)
{
printf ("my dog has %u fleas.\n", argument);
}
void function2 (unsigned int argument, func_ptr argument2)
{
printf ("my cat has %u fleas.\n", argument);
argument2 (argument);
}
void function3(func_ptr argument)
{
function2 (123, argument);
}
int main (void) {
function2 (4, function1);
function3 (function1);
return 0;
}
示例使用/输出
$ ./bin/fncptr
my cat has 4 fleas.
my dog has 4 fleas.
my cat has 123 fleas.
my dog has 123 fleas.
仔细看看,如果您有其他问题,请告诉我。
答案 2 :(得分:1)
C标准不允许将void *
转换为指向某个函数的指针,也不允许再转回 - void *
的措辞位于6.3.2.3p1:
指向void的指针可以转换为指向任何对象类型的指针。指向任何对象类型的指针可以转换为指向void的指针,然后再返回;结果应该等于原始指针。
但是,函数不是对象,因此您甚至无法移植到void *
的函数指针。
现在,据说可以将指针转换为整数,然后再返回:
6任何指针类型都可以转换为整数类型。除了之前指定的以外,结果是实现定义的。 如果结果无法以整数类型表示,则行为未定义。结果不必位于任何整数类型的值范围内。
如果您的(函数)指针是64位且int
32位,则行为未定义。对于指向对象的指针,您可以使用(u)intptr_t
- 但这不能保证与函数指针一起使用。相反,对于函数指针,可以保证可以将任何函数指针转换为另一个,因此可以使用generic function pointer,例如
typedef void (*funcptr)(void);
并在调用之前将其转换为正确的函数指针类型。
如果您还需要整数,则必须使用联合
union int_or_funcptr {
int integer;
funcptr function;
}
如果需要该函数,请分配或读取union的function
成员,在调用它之前正确地进行转换。