由于 C++03/C++11 中指针数组的常量性而导致的链接错误
Linking error due to constness of the pointer array in C++03/C++11
此问题可在 -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'
是编译器错误还是语言limitation/feature?
正如 Quentin 所注意到的,n4296 草案在第 3.5 章“程序和链接”[basic.link]§3(强调我的)
A name having namespace scope (3.3.6) has internal linkage if it is the name of
(3.1) — a variable, function or function template that is explicitly declared static; or,
(3.2) — a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously
declared to have external linkage;
当您将 arr
声明为 const 时,它被隐含地赋予了内部链接。修复很简单:
/* main.cpp */
extern const char* const arr[2] = {"Hello", "World"};
但最佳做法是建议使用 arr
将 extern const char* const arr[2];
包含在所有使用 arr
的文件中,以便正确共享声明,然后添加其中一个文件 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"};
此问题可在 -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'
是编译器错误还是语言limitation/feature?
正如 Quentin 所注意到的,n4296 草案在第 3.5 章“程序和链接”[basic.link]§3(强调我的)
A name having namespace scope (3.3.6) has internal linkage if it is the name of
(3.1) — a variable, function or function template that is explicitly declared static; or,
(3.2) — a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage;
当您将 arr
声明为 const 时,它被隐含地赋予了内部链接。修复很简单:
/* main.cpp */
extern const char* const arr[2] = {"Hello", "World"};
但最佳做法是建议使用 arr
将 extern const char* const arr[2];
包含在所有使用 arr
的文件中,以便正确共享声明,然后添加其中一个文件 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"};