19

我让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 行中的代码。

打印函数地址时删除警告我缺少什么?

4

4 回答 4

17

这本质上是打印函数指针的唯一可移植方式。

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');
于 2012-06-07T14:03:29.277 回答
6

这整个想法确实是不可移植的,因为一些系统使用不同大小的指针来指向代码和数据。

您真正需要的是关于函数指针有多大的特定于平台的知识,以及转换为该大小的整数类型。不幸的是,我认为没有人标准化一个可以保存任何数据指针的intfuncptr_t类比。intptr_t


正如 R.在他的回答signed中指出的那样,您始终可以将指针视为 (可能or unsigned)的数组char,这样您就不需要任何正确大小的整数类型。

于 2012-06-07T13:37:28.963 回答
5

它就在警告中:ISO C 禁止将函数指针转换为对象指针类型,其中包括void*. 另请参阅此问题

您根本无法以可移植的方式打印函数的地址,因此您无法摆脱警告。

您可以使用@R.. 的建议打印函数指针。

于 2012-06-07T13:37:44.987 回答
4

虽然将函数指针转换为 void 指针在技术上是危险的,但在 POSIX 标准中使用将函数指针转换为 void 指针,因此几乎可以肯定它适用于大多数编译器。

抬头看dlsym()

于 2012-06-07T13:38:27.423 回答