如何格式化函数指针?

L̲̳*_*̲̳̳ 44 c function-pointers

有没有办法在ANSI C中打印指向函数的指针?当然这意味着你必须将函数指针强制转换为void指针,但似乎不可能?

#include <stdio.h>

int main() {
    int (*funcptr)() = main;

    printf("%p\n", (void* )funcptr);
    printf("%p\n", (void* )main);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

$ gcc -ansi -pedantic -Wall test.c -o test
test.c:在函数'main'中:
test.c:6:警告:ISO C禁止将函数指针转换为对象指针类型
test.c:7:warning :ISO C禁止将函数指针转换为对象指针类型
$ ./test
0x400518
0x400518

它"工作",但非标准...

caf*_*caf 44

唯一合法的方法是使用字符类型访问构成指针的字节.像这样:

#include <stdio.h>

int main() {
    int (*funcptr)() = main;
    unsigned char *p = (unsigned char *)&funcptr;
    size_t i;

    for (i = 0; i < sizeof funcptr; i++)
    {
        printf("%02x ", p[i]);
    }
    putchar('\n');

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

将函数指针作为一个void *或任何非字符类型,如dreamlax的答案所做的那样,是未定义的行为.

构成函数指针的那些字节实际上意味着与实现有关.例如,它们只能表示函数表的索引.

  • @Chris:`uintptr_t`与函数指针无关,是可选的.因此,从POV写出一些完全便携的东西,它并不是更好. (9认同)
  • 不幸的是,在为打印函数指针添加`printf`格式说明符之前,它是您在严格符合C时可以做的最好的.Endianness是一个红色鲱鱼 - 不能保证"函数指针"是任何类型的数字(例如,它可能是函数名的前64个字符,当使用函数指针进行调用时,在符号表中查找.这就是为什么函数指针不能与其他指针类型进行转换的原因 - 这样实现它在如何实现它们方面具有很大的自由度. (5认同)

Dus*_*tin 5

可以使用可以解决警告/错误的联合,但结果仍然(很可能)是未定义的行为:

#include <stdio.h>

int
main (void)
{
  union
  {
    int (*funcptr) (void);
    void *objptr;
  } u;
  u.funcptr = main;

  printf ("%p\n", u.objptr);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

你可以比较两个函数指针(例如printf ("%i\n", (main == funcptr));)使用if语句来测试它们是否相等(我知道这完全违背了目的并且很可能是无关紧要的),但实际输出的是函数指针的地址,会发生什么取决于目标平台的C库和编译器的供应商.