无法使用来自另一个翻译单元的函数指针初始化静态结构?

Jos*_*man 5 c c99 c89

Python文档声称以下内容不适用于"某些平台或编译器":

int foo(int);  // Defined in another translation unit.
struct X { int (*fptr)(int); } x = {&foo};
Run Code Online (Sandbox Code Playgroud)

具体来说,Python文档说:

我们想把它分配给tp_new插槽,但是为了便携起见,我们不能,在某些平台或编译器上,我们不能用另一个C模块中定义的函数静态初始化一个结构成员,所以,相反,我们将在调用PyType_Ready()之前在模块初始化函数中分配tp_new槽.- http://docs.python.org/extending/newtypes.html

以上标准C89和/或C99?什么编译器具体无法处理上述问题?

Die*_*Epp 2

根据n1570 6.6第9段,函数的地址是地址常量,根据6.7.9这意味着它可以用于初始化全局变量。我几乎可以肯定这也是有效的 C89。

然而,

在健全的平台上,函数指针(或除 之外的任何指针)的值NULL仅在运行时才知道。这意味着结构的初始化要到运行时才能进行。这并不总是适用于可执行文件,但它几乎总是适用于共享对象,例如 Python 扩展。我建议阅读 Ulrich Drepper 关于该主题的文章(链接)。

我不知道这个问题在哪些平台上出现,但如果 Python 开发人员提到它,几乎可以肯定是因为其中一个人被它咬了。如果您真的很好奇,请尝试查看旧的 Python 扩展并查看提交日志中是否有适当的消息。

编辑:看起来大多数Python模块只是做正常的事情并静态初始化类型结构,例如static type obj = { function_ptr ... };. 例如,查看mmap动态加载的模块。