冲突变量声明的编译错误:“与'C'连接的新声明冲突”

时间:2015-07-10 20:36:10

标签: 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://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)

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

顺便说一句,我并不反对改变代码;我想知道是否还有更多事情发生,而不仅仅是“标准说这是形成不良”。

1 个答案:

答案 0 :(得分:3)

我查看了各种*堆栈站点,并且主要发现了与此主题相关的有关具有冲突链接规范的函数的问题。

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

  

标准在7.5 / 5中说:"如果相同功能或对象的两个声明指定不同的链接规范[...],如果声明出现在同一个翻译单元中,则程序格式错误[ ...]&#34 ;.这就是为什么评论6中的代码现在被拒绝了。

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

然后我发现了这篇关于storage class specifiers的文章和一篇关于language linkage的文章。我没有看到那些与我迄今学到的东西相冲突的文章中的任何内容;第二个说:

  

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