【发布时间】:2016-08-14 04:46:31
【问题描述】:
我正在尝试找出以下前向声明在 ANSI-C 中是否有效:
第一个文件:
extern void * fptr; // opaque forward declaration.
int main (void) {
fptr = NULL; // set the function pointer to NULL
}
第二个文件:
typedef int (*fptr_t)(int);
fptr_t fptr; // real declaration of the function pointer
对我来说,这应该是无效的,因为 fptr 如果用两种不同的类型声明,但 gcc 和 clang 都没有给出任何警告。
我会对 C11 标准的精确点更感兴趣,这些点可以得出结论为什么它有效(或无效)。
编辑:在 C11 标准中,6.2.7:2 说:
引用同一对象或函数的所有声明都应具有 兼容类型;否则,行为未定义。
但我找不到如何确定void* 是否与fptr_t 兼容。
【问题讨论】:
-
如果两个声明永远不会一起出现在同一个编译单元中,您将不会出现编译时错误。链接目标文件时,如果可以解析符号引用,即使类型不兼容,也不会出现错误。这与在一个文件中将变量声明为
int而在另一个文件中声明为float没有什么不同。 -
我了解编译器看不出问题。但是,如果您在一个文件中将变量声明为 int 而在另一个文件中声明为 float,您会遇到麻烦,不是吗?这个案子怎么办?
-
据我了解的标准,如果类型是“兼容的”就可以了。但在这种情况下,它们是否存在?
-
你是对的,但在这种情况下,我相信它是特定于实现的,它还取决于你如何使用变量。如果指针类型之间的分配不会导致表示形式发生任何变化,它只会执行您想要的操作。但这不是你应该依赖的东西。
-
@LPs 不,如果编译器在同一个编译单元中看到这两个声明,它会报错。 链接器 是会或不会发出警告的位置。您将链接器与编译器混淆了。它们非常不同。
标签: c function-pointers