我有以下代码:
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;
但似乎无法找到合适的人。
答案 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保证这会起作用,因此关于“实现定义结果”的部分不那么可怕了。