【问题标题】:global std::string and one definition rule全局 std::string 和一个定义规则
【发布时间】:2013-11-25 14:36:30
【问题描述】:

我有一个包含以下定义的头文件

const std::string error[] = {"a", "b"};

现在我将此文件包含在两个不同的翻译单元中并编译源代码。一切正常,但为什么呢?这预计会破坏one definition rule

现在更有趣的是,我正在改变类型

const char* error[] = {"a", "b"};

这就是预期的错误

multiple definition of `error'

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

【问题讨论】:

    标签: c++ one-definition-rule


    【解决方案1】:

    constnamespace-scoped 变量提供内部链接,这就是它起作用的原因,实际上与

    static const std::string error[] = {"a", "b"};
    

    第二个不起作用,因为它不是 const 的变量,而是它所包含的 chars。

    【讨论】:

    • 不知道 const 提供了内部链接。谢谢。标准中有提到吗?
    • 是的,找到了。 Objects declared const and not explicitly declared extern have internal linkage.
    • @axe 有什么参考价值?
    • 没关系。这是 7.1.1 存储类说明符 [dcl.stc],第 7 段。
    • 另请注意,这是 C++ 与 C 不兼容的少数几个地方之一。有关详细信息和基本原理,请参阅 this question
    【解决方案2】:

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

    第二个例子不是const——指针指向常量对象,但它们本身是可变的。所以这个数组是有外部链接的,并且服从一个定义规则。

    【讨论】:

      【解决方案3】:

      来自MSDN

      在 C 中,常量值默认为外部链接,因此它们只能出现在源文件中。在 C++ 中,常量值默认为内部链接,这允许它们出现在头文件中。

      【讨论】:

        猜你喜欢
        • 2020-04-11
        • 1970-01-01
        • 2019-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多