全局std :: string和一次定义规则

3
我有一个头文件,其中包含以下定义。
const std::string error[] = {"a", "b"};

现在我将此文件包含在两个不同的翻译单元中,并编译源代码。一切正常,但为什么呢?这应该会破坏 "一个定义规则"。
现在更有趣的是,我正在改变类型。
const char* error[] = {"a", "b"};

这里出现了预期错误。

multiple definition of `error'

对于intcharshort和其他整型类型,它的工作方式与std::string相同。这是什么意思?

3个回答

12

const 使得命名空间作用域的变量拥有内部链接,因此它可以工作,实际上与以下内容效果相同:

static const std::string error[] = {"a", "b"};
第二个不起作用是因为不是变量是const,而是它由char组成。

1
不知道const会给出内部链接。谢谢。标准中有提到吗? - axe
2
找到了。被声明为const且没有显式声明为extern的对象具有内部链接。 - axe
@axe 这是什么引用? - BoBTFish
没关系。这是7.1.1存储类别说明符[dcl.stc]的第7段。 - BoBTFish
还要注意,这是C++与C不兼容的少数几个地方之一。有关详细信息和基本原理,请参见此问题。 - ComicSansMS

2

const 声明的全局变量具有内部链接,就像它们也被声明为 static 一样。您可以在不同的翻译单元中定义具有相同名称的内部变量,因此在第一个示例中发生了这种情况 - 包括标题的每个单元都获得了自己的数组副本。

第二个示例不是 const - 指针指向常量对象,但它们本身是可变的。因此,该数组具有外部链接,并受到“一个定义规则”的限制。


0

MSDN

在C语言中,常量的默认链接性为外部链接,因此它们只能出现在源文件中。而在C++中,常量的默认链接性为内部链接,这使得它们可以出现在头文件中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接