C++ 冲突变量声明的编译器错误:";与'的新声明冲突;C';“联系”;

C++ 冲突变量声明的编译器错误:";与'的新声明冲突;C';“联系”;,c++,linkage,name-mangling,C++,Linkage,Name Mangling,我遇到了一些无法在较新的编译器上构建的遗留代码。简单的例子是: 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://

我遇到了一些无法在较新的编译器上构建的遗留代码。简单的例子是:

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
error: previous declaration of 'int x' with 'C++' linkage
error: conflicts with new declaration with 'C' linkage
GCC的输出:

error: declaration of 'x' has different language linkage
error: previous declaration of 'int x' with 'C++' linkage
error: conflicts with new declaration with 'C' linkage
这让我很惊讶,因为编译器不会以任何特殊方式损坏
x
,而且据我所知,除了调试信息之外,对象文件没有什么不同(基于我使用objdump/readelf进行的公认的肤浅测试)

我的问题:如果没有功能上的差异,为什么这是一个错误


顺便说一句,我并不反对修改代码;我想知道是否有比“标准说这是不正确的”更重要的事情发生了。

我查看了各种*堆栈站点,主要发现了与链接规范冲突的功能相关的问题

我的[第一个]答案是:

该标准在7.5/5中说:“如果同一函数或对象的两个声明指定了不同的链接规范[…],那么如果这些声明出现在同一个翻译单元[…],则程序是格式错误的。”。这就是为什么注释6中的代码现在被拒绝的原因

无论我的假设是否正确(关于POD变量的C/C++链接之间的函数差异),似乎这个错误是为了防止错误的样式

然后我找到了这篇关于和一篇关于的文章。到目前为止,我在这些文章中没有看到任何与我所学到的相冲突的东西;第二条说:

同样,同一名称空间中的两个变量不能有两种不同的语言链接


我可以问一下为什么投票失败吗?