强制转换为函数指针?

时间:2012-03-04 14:50:50

标签: c function-pointers c89

我有以下代码:

long fp = ...
void (*ptr)(long, char*, char*) = fp;

long fp是一个正确的函数指针,它以long形式出现。我正在获得标准“从没有强制转换的int生成指针”警告。我希望能够编译:

-std=iso9899:1990 -pedantic-errors

将警告变为错误。问题是:什么是正确的演员?我尝试了各种猜测,例如:

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp;

但似乎无法找到合适的人。

4 个答案:

答案 0 :(得分:7)

“正确”的演员是:

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp;

显然,这可以用合适的typedef来整理。

但不管怎样,其结果都是实现定义的。如果可以,请避免这种情况,并将指针保持在指针类型中。如果可用的话,最好的事情是使用intptr_t

答案 1 :(得分:7)

可能是这样的:

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp;

但我的建议是使用typedef而忘记所有这些混乱:

typedef void (* fnPtr)(long, char, char*);
fnPtr ptr = (fnPtr) fp;

答案 2 :(得分:4)

唯一的“正确”方式根本不是投射,而是复制二进制表示:

long fp;
void (*ptr)(long, char*, char*);

memcpy(&ptr, &fp, sizeof ptr);

答案 3 :(得分:2)

这里的主要问题是,ANSI-C不允许这样做,尽管依赖于此功能的无数C-API依然存在。因此,在使用-pedantic进行编译时,您可能会遇到麻烦。 正如其他海报所暗示的那样,你可以通过使用诸如memcpy()之类的东西或联合类型来阉割演员。

顺便说一下,POSIX保证这会起作用,因此关于“实现定义结果”的部分不那么可怕了。