ikh*_*ikh 5 c++ function linkage
我在声明中看到了一个奇怪的代码std::atexit:
extern "C" int atexit( void (*func)() );
extern "C++" int atexit( void (*func)() ); // ... why are there two functions?
Run Code Online (Sandbox Code Playgroud)
我想这是某种函数重载,但它似乎显然是错误的.
那是什么?为什么有必要?
这是 cppreference 有点误导。
使用不同的存储类说明符两次声明同一函数是非法的,并且会导致构建失败。如果您查看libstdc++(GCC 的标准库实现)的源代码,您会发现实际上只extern "C"提供了版本。
尽管[C++11: 18.5]与 cppreference 一样列出了这两个声明,但这并不意味着两者都可以在单个实现中使用;这意味着实现可以选择声明其中任何一个:也就是说,它说明了[C++11: 17.6.4.3.3/4]:
使用外部链接声明的标准 C 库中的每个函数签名都保留给实现,用作具有 extern“C”和 extern“C++”链接的函数签名[..]
还:
[C++11: 17.6.2.3/2]:使用外部链接声明的 C 标准库中的名称是否具有extern "C"或extern "C++"链接是实现定义的。建议实现extern "C++"为此目的使用链接
该规则在这里明确明确:
[C++11: 7.5/5]:如果两个声明将具有相同名称和参数类型列表(8.3.5)的函数声明为同一名称空间的成员,或者将具有相同名称的对象声明为同一名称空间的成员,并且声明为名称提供了不同的语言链接,程序格式错误;如果声明出现在不同的翻译单元中,则不需要诊断。[..]
在我看来,这确实会在标准的其他地方引起一些问题;例如:
[C++11: 25.5/2]:内容与标准 C 库头相同,<stdlib.h>但有以下例外:
[C++11: 25.5/3]:函数签名:Run Code Online (Sandbox Code Playgroud)bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));被两个声明替换:
Run Code Online (Sandbox Code Playgroud)extern "C" void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); extern "C++" void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));两者的行为都与原始声明相同。