我让gcc
使用-Wall -pedantic
编译以下示例:
#include <stdio.h>
int main(void)
{
printf("main: %p\n", main); /* line 5 */
printf("main: %p\n", (void*) main); /* line 6 */
return 0;
}
我明白了:
main.c:5: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int (*)()’
main.c:6: warning: ISO C forbids conversion of function pointer to object pointer type
第5行改变了第6行的代码。
打印功能地址时删除警告我缺少什么?
答案 0 :(得分:15)
这实际上是打印函数指针的唯一可移植方式。
size_t i;
int (*ptr_to_main)() = main;
for (i=0; i<sizeof ptr_to_main; i++)
printf("%.2x", ((unsigned char *)&ptr_to_main)[i]);
putchar('\n');
答案 1 :(得分:4)
这个想法确实是不可移植的,因为有些系统使用不同大小的指针代码和数据。
你真正需要的是关于函数指针有多大的平台特定知识,以及对该大小的整数类型的强制转换。不幸的是,我认为没有人将intfuncptr_t
标准化为intptr_t
,它可以容纳任何数据指针。
正如R. note in his answer所示,您始终可以将指针视为(可能是signed
或unsigned
)char
的数组,这样您就不需要了任何正确大小的整数类型。
答案 2 :(得分:4)
警告就在那里:ISO C禁止将函数指针转换为对象指针类型,其中包括void*
。另请参阅this question。
您无法以便携方式打印函数的地址,因此您无法摆脱警告。
您可以使用@R ..的建议打印函数指针。
答案 3 :(得分:4)
虽然将函数指针转换为void指针在技术上是危险的,但在POSIX标准中使用将函数指针转换为void指针,因此几乎可以肯定它适用于大多数编译器。
查找dlsym()
。