【问题标题】:Compiler error for conflicting variable declarations: "conflicts with new declaration with 'C' linkage"冲突变量声明的编译器错误:“与带有‘C’链接的新声明冲突”
【发布时间】:2015-07-10 20:36:10
【问题描述】:

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

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 浅层测试)

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

顺便说一句,我不反对更改代码;我想知道除了“标准说这是不正确的”之外,是否还有更多的事情发生。

【问题讨论】:

  • 请问为什么投反对票?

标签: c++ linkage name-mangling


【解决方案1】:

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

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

该标准在 7.5/5 中说:“如果同一函数或对象的两个声明指定了不同的链接规范 [...] 如果声明出现在同一翻译单元中 [... ]”。这就是为什么评论 6 中的代码现在被拒绝的原因。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多