我正在为嵌入式系统编写代码。编译器是GCC衍生物。 以下代码是否正确?
void *voidPointer = 0;
int (*functionPointer)(int a);
int testFunction(int a)
{
return(a+1);
}
void registerFunction(void *pvFunctionAddress)
{
voidPointer = pvFunctionAddress;
}
main()
{
...
registerFunction(testFunction);
functionPointer = voidPointer;
x = functionPointer(17);
...
}
现在x应该具有值18。 编译器没有显示错误 - 但这是正确的吗? 或者我们覆盖堆栈上的一些内存。
感谢。
答案 0 :(得分:3)
不,它永远不会“正确”,因为严格来说C禁止void *
和函数指针之间的转换。
如果它有效,那是因为特定的编译器允许它用于特定目标(操作系统+硬件组合)。
答案 1 :(得分:3)
严格地说,根据C标准,void*
不能保证能够保存函数指针。我相信POSIX确实要求函数指针能够存储在void*
中(以支持dlsym()
函数)。见https://stackoverflow.com/a/12359083/12711
答案 2 :(得分:0)
我们这样说:
在C中,函数由适当程序集中第一条指令的地址标识,该程序开始执行它的调用约定,因此void*
是一个有效的存储类,如果调用约定是一个存储它编译时常量。对于最常用的CPU架构,它是。
如果您的代码适用于您的目标硬件的编译器,那么它在这个意义上是正确的。
这是一个简单的比较:
uintptr_t i = NULL;
是有效的C,因为uintptr_t
(通常unsigned long int
)与void *
(NULL
的类型)是相同的存储类。