变量声明冲突的编译器错误:"conflicts with new declaration with 'C' linkage"

Compiler error for conflicting variable declarations: "conflicts with new declaration with 'C' linkage"

我 运行 跨越一些无法在较新的编译器上构建的遗留代码。简化示例:

int x;
extern "C" { int x }; // conflicts with C++ linkage above
// note: without the braces it would've been equivalent to:
// extern "C" { extern int x; }
//
// for reference, see the notes section here:
//   http://en.cppreference.com/w/cpp/language/language_linkage#notes

旧的编译器没有标记它,但 gcc(从 4.1.2 开始)和 clang 都标记了它。

Clang 的输出:

error: declaration of 'x' has different language linkage

GCC 的输出:

error: previous declaration of 'int x' with 'C++' linkage
error: conflicts with new declaration with 'C' linkage

这让我感到惊讶,因为编译器不会以任何特殊方式破坏 x,据我所知,目标文件除了调试信息外没有什么不同(基于我承认的浅测试objdump/readelf)

我的问题:如果没有功能差异,为什么会出现错误?

顺便说一句,我不反对更改代码;我想知道除了 "the standard says this is ill formed".

之外是否还有其他事情发生

我浏览了各种 *stack 站点,发现大多数关于此主题的问题与链接规范冲突的函数有关。

我在 gcc bugzilla database 中找到了我的 [第一个] 答案:

The standard says in 7.5/5: "If two declarations of the same function or object specify different linkage-specifications [...] the program is ill-formed if the declarations appear in the same translation unit [...]". That is why code like that in comment 6 is now rejected.

无论我的假设是否正确(关于 POD 变量的 C/C++ 链接之间的功能差异),看来错误是为了防止不良风格。

然后我找到了这篇关于storage class specifiers and one about language linkage的文章。我在那些文章中没有看到任何与我目前所学相冲突的内容;第二个说:

Likewise, two variables in the same namespace cannot have two different language linkages.