【问题标题】:Linking error due to constness of the pointer array in C++03/C++11由于 C++03/C++11 中指针数组的 constness 导致的链接错误
【发布时间】:2016-06-02 12:51:37
【问题描述】:

-std=c++14 之前的 g++ 中可以重现此问题。由于以下代码中突出显示的const,会生成链接错误。如果删除 RHS const,它就会消失。

/* main.cpp */
const char* const arr[2] = {"Hello", "World"};
//          ^^^^^
int main () {}

/* foo.cpp */
extern const char* const arr[2];
//                 ^^^^^
const char* foo () { return arr[0]; }

编译时:g++ [-std=c++11] main.cpp foo.cpp,它给出以下链接错误:

In function `foo()': undefined reference to `arr'  

是编译器错误还是语言限制/功能?

【问题讨论】:

  • const 命名空间范围内的变量 are implicitly static,除非您添加 extern。我不确定为什么-std=c++14 的行为会发生变化。
  • 不应该将extern const char* const arr[2]; 放在同时包含main.cppfoo.cpp 的头文件中吗?
  • @Quentin 我不知道为什么 OP 说 pre c++14, g++ 5.1.0 在任何模式下都会产生错误(c++14 c++17),你的评论应该是答案
  • 无法在 GCC 6.1 上复制,所有std 标志的行为都是一致的。

标签: c++ c++11 constants linker-errors compiler-bug


【解决方案1】:

正如 Quentin 所注意到的,n4296 草案在第 3.5 章程序和链接 [basic.link] §3 中明确说明了这一点(强调我的)

具有命名空间范围 (3.3.6) 的名称如果是
的名称,则具有内部链接 (3.1) — 显式声明为静态的变量、函数或函数模板;或者,
(3.2) — 非易失性 const 限定类型的变量,既没有显式声明 extern,也没有以前声明 声明有外部链接;

当您将arr 声明为 const 时,它被隐含地赋予了内部链接。修复很简单:

/* main.cpp */
extern const char* const arr[2] = {"Hello", "World"};

但最佳实践建议使用 arr 在所有文件的标头中包含 extern const char* const arr[2];,以便正确共享声明,然后添加其中一个文件 const char* const arr[2] = {"Hello", "World"};,从而有效地产生:

/* main.cpp */
extern const char* const arr[2]; // directly or more likely through an include...
...
const char* const arr[2] = {"Hello", "World"};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 2017-10-04
    • 2015-09-25
    • 2018-04-16
    相关资源
    最近更新 更多