与“C”链接的函数声明冲突

zde*_*o.s 4 c++

以下编译无错误:

\n
extern "C" void func( void );\nextern void func( void );\n
Run Code Online (Sandbox Code Playgroud)\n

如果我改变声明的顺序,

\n
extern void func( void );\nextern "C" void func( void );\n
Run Code Online (Sandbox Code Playgroud)\n

我收到编译器错误:conflicting declaration of \xe2\x80\x98void func()\xe2\x80\x99 with \xe2\x80\x98C\xe2\x80\x99 linkage
\nC++ 标准说:

\n
    \n
  • 最多一个具有特定名称的函数可以具有“C”链接(无论命名空间如何)
  • \n
\n

在这两种情况下,它是相同的功能。我的假设是 C++ 编译器在内部存储它将编译的函数签名。在第一个示例中,编译器认为第二个声明有效并使用第一个声明进行编译。在第二个例子中,情况并非如此。它将两个声明重新评级为不同的声明。
\n其背后的技术细节是什么?
\ngcc 9.4.0 和 msvc 19.29.30147

\n

Bri*_*ian 5

不需要重新声明函数来重复其链接规范。来自 cppreference 的每种语言链接

使用语言规范声明函数后,可以在没有链接规范的情况下重新声明函数,第二次声明将重用第一个语言链接。反之则不然:如果第一个声明没有语言链接,则假定"C++",并且用另一种语言重新声明是错误的。

在第一个代码片段中,您声明了一个带有"C"链接的函数,然后在没有显式链接的情况下重新声明了它。这没关系;假定原始链接。然而,在第二个片段中,您声明了一个具有(隐式)"C++"链接的函数,然后尝试使用链接重新声明它"C"——这是一个冲突,因此会出现错误。