在C++ 03/C++ 11中链接由于指针数组的常量引起的错误

iam*_*ind 5 c++ const linker-errors compiler-bug c++11

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

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

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

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

In function `foo()': undefined reference to `arr'  
Run Code Online (Sandbox Code Playgroud)

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

Ser*_*sta 3

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

\n\n
\n

具有名称空间范围 (3.3.6) 的名称,如果它是
显式声明为静态的变量、函数或函数模板的名称,则具有内部链接。 \n (3.1) \xe2\x80\x94 ;或者,
\n (3.2) \xe2\x80\x94一个非易失性 const 限定类型的变量,既没有显式声明为 extern,也没有事先声明为具有外部链接;

\n
\n\n

当您声明arr为 const 时,它会隐式地给出内部链接。修复很简单:

\n\n
/* main.cpp */\nextern const char* const arr[2] = {"Hello", "World"};\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
/* main.cpp */\nextern const char* const arr[2]; // directly or more likely through an include...\n...\nconst char* const arr[2] = {"Hello", "World"};\n
Run Code Online (Sandbox Code Playgroud)\n