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