我正在重构一个c ++代码,有一些我无法理解的东西.代码在头文件中声明一组数组,然后在需要时在源文件中包含该头文件.除了一个"const char*[]"数组之外,所有数组都是"const unsigned char []".后者被#ifdef SOMETHING所包围.如果没有定义SOMETHING,则代码构建成功,否则我只会为此"char*[]"获得多个定义的链接器错误.
作为修复,我可以通过将"static"添加到"const char*XX [3] = {"X","Y","Z"}"来消除这些链接器错误.这将使定义保持特定于翻译单元.
但是,我无法理解为什么"多个定义"错误只发生在"const char*[]"数组而不是其他"const unsigned char []",尽管它们之前没有"static"关键字?有人可以向我解释一下吗?
命名空间范围内的常量变量隐式具有内部链接(如果愿意,它们是隐式的static
).以下声明并定义了两个不同的对象.
// A.cpp // B.cpp
const T foo = 1; const T foo = 2;
Run Code Online (Sandbox Code Playgroud)
如果你想要外部联系,你必须说extern const T foo;
.
相比之下,命名空间范围内的非常量变量具有外部链接(如果您愿意,它们是隐式声明的extern
)并且都表示相同的对象,因此您违反了单定义规则:
// A.cpp // B.cpp
U bar = 1; U bar = 2; // ODR violation
Run Code Online (Sandbox Code Playgroud)
在这里,如果你想要内部联系,你必须说static U bar;
.
这是你的情况.你有T = char []
和U = const char * []
.(这里按8.3.4/1 const T
生成类型const char []
.)
解决方案是,如果变量具有外部链接,则不在头中定义变量,因为标头包含在多个转换单元中.相反,只在标头中声明变量并在一个单独的翻译单元中定义它:
library.h:
extern U bar; // in your case, extern const char * XX[];
Run Code Online (Sandbox Code Playgroud)
library_impl.cpp:
#include "library.h"
U bar = 3;
Run Code Online (Sandbox Code Playgroud)