使用正常功能,可以编写
extern "C" int Frotz(int); // in a header
int Frotz(int x) { return x; }
然而,对于函数指针,这似乎在编译器之间的实现不一致。
extern "C" int Klutz(int (*)(int), int);
int Klutz(int (*fptr)(int), int x) { return (*fptr)(x); }
在声明中,参数也是extern "C"
. 在定义中,大多数编译器似乎都匹配这些函数并生成Klutz
一个extern "C"
函数。然而,Sun 和 Cray 编译器将这些函数解释为不同的,产生一个重载的int Klutz(int (*fptr)(int), int x)
,然后产生一个链接时错误。
尽管 C++98 和 C++11 的第 7.5.5 节保证对 的解释Frotz
,但我无法判断标准是否extern "C"
应在检查重载之前或之后发生匹配是否模棱两可。
上面应该Klutz
生成一个损坏的(C++)符号还是一个extern "C"
符号?
编辑 1
我可以使用 typedef 来消除具有 C 或 C++ ABI 的函数指针的歧义,但我感兴趣的是这里的代码 (a) 是否定义Klutz
为具有 C++ 链接,(b) 将其定义为具有 C 链接,或者 (c)根据标准是模棱两可的,因此编译器可以自由选择如何解释它。
编辑 2
这似乎是一个已知问题,至少对于那些带有可搜索错误跟踪器的编译器而言。在我的测试中,GCC、Clang、Intel、MSVC、IBM XL、PathScale、PGI 和 Open64 都无法区分除了语言链接之外相同的函数类型,这是标准明确要求的(参见第 7.5.1 节,引用于接受的答案)。解决这个问题会破坏很多现有代码并需要更改 ABI。我不知道有任何编译器实际上对 C 与 C++ 语言链接使用不同的调用约定。