0

我正在为嵌入式系统编写代码。编译器是 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。编译器没有显示错误 - 但这是正确的吗?或者我们是否覆盖了堆栈上的一些内存。

谢谢。

4

3 回答 3

3

不,它永远不可能是“正确的”,因为严格来说 C 禁止void *函数指针和函数指针之间的转换。

如果它有效,那是因为特定的编译器允许它用于特定的目标(操作系统+硬件组合)。

于 2012-11-20T15:45:00.083 回答
3

严格来说,根据 C 标准,void*不能保证 a 能够持有函数指针。我相信 POSIX 确实要求函数指针能够存储在 avoid*中(以支持该dlsym()函数)。见https://stackoverflow.com/a/12359083/12711

于 2012-11-20T15:45:41.643 回答
0

让我们这样说:

在 C 中,函数由开始执行它的相应程序集中的第一条指令的地址和它的调用约定来标识,因此void*如果调用约定是编译时常量,则 a 是一个有效的存储类来存储它。对于最常用的 CPU 架构,它是。

如果您的代码适用于您的目标硬件的编译器,那么它在这个意义上是正确的。

这是一个简单的比较:

uintptr_t i = NULL;

是有效的 C,因为uintptr_t(通常) 与(type of )unsigned long int是相同的存储类。void *NULL

于 2012-11-20T16:06:51.187 回答