POSIX对C中指针类型的限制

Nis*_*röm 13 c posix function-pointers dlsym

背景

POSIX标准增加了很多的库函数和其它标识符C语言.在dlsym()功能的描述中,它说(我强调):

概要

#include <dlfcn.h>

void *dlsym(void *restrict handle, const char *restrict name);
Run Code Online (Sandbox Code Playgroud)

描述

对dlsym()函数将获得符号的地址(一个功能标识符或数据对象标识符)...

C标准不保证函数指针可以转换为a void *,甚至不能保证指针的大小相同.这有效地增加了对C类型系统的额外限制.

我的问题是:

  • 对于C类型系统的这种限制是否有规范性参考,或者它只能从某些库函数的描述中推导出来?
  • POSIX甚至可以在一个系统上实现吗? sizeof (function pointer) > sizeof (void *)

参考

Sha*_*our 7

对dlsym()引用说,转换不是由C标准但符合标准的实现必须正确地做这项工作定义.因此,在无法使其工作的系统上,这将不是一个符合要求的实现,并且可能会记录下来:

请注意,从void*指针转换为函数指针,如:

fptr = (int (*)(int))dlsym(handle, "my_function");
Run Code Online (Sandbox Code Playgroud)

不是由ISO C标准定义的.此标准要求此转换在符合要求的实现上正常工作.

有一篇旧文章从C++的角度讨论这个问题,并链接到旧版本的dlsym()引用,并有一个更详细的解释:

ISO C标准不要求指向函数的指针可以来回转换为指向数据的指针.实际上,ISO C标准不要求void*类型的对象可以保存指向函数的指针.但是,支持XSI扩展的实现确实需要void*类型的对象可以保存指向函数的指针.但是,将指向函数的指针转换为指向另一种数据类型(void*除外)的指针的结果仍未定义.请注意,如果尝试从void*指针到函数指针的转换,则需要符合ISO C标准的编译器生成警告,如下所示:

fptr = (int (*)(int))dlsym(handle, "my_function");
Run Code Online (Sandbox Code Playgroud)

由于此处提到的问题,未来版本可以添加新函数以返回函数指针,或者可以弃用当前接口以支持两个新函数:一个返回数据指针而另一个返回函数指针.

  • "需要产生警告".这不是真的,因为C标准没有警告的概念. (2认同)