【问题标题】:Correctly declaring extern variable in a namespace c++在命名空间 c++ 中正确声明外部变量
【发布时间】:2018-09-12 07:15:37
【问题描述】:

我有一些 const 变量,我希望它们的值在多个源文件之间共享。我还希望将变量的范围限制为命名空间。我不确定执行此操作的最佳/正确方法?

我可以使用 #define 但希望类型安全。

到目前为止,我有以下工作:

文件0.h

#pragma once

namespace Namespace1
{
   extern const int variable1;
   extern const int variable2;
}

文件0.cpp

const int Namespace1::variable1 = 10;
const int Namespace1::variable2 = 10;

Source1.cpp

#include "File0.h"
int result1 = Namespace1::variable1 + Namespace1::variable2;

Source2.cpp

#include "File0.h"
const int result2 = Namespace1::variable1 + Namespace1::variable2;

使用 extern 如何知道值何时被初始化?

【问题讨论】:

    标签: c++ c++03


    【解决方案1】:

    使用 extern 如何知道值何时被初始化?

    你没有。这被称为static initialization order fiasco。不同翻译单元中命名空间范围静态对象的初始化以未指定的顺序完成。如果一个静态对象的初始化依赖于不同转换中的另一个对象,则行为未定义。

    即使是简单的整数,也可能发生这种灾难。由于您的意图是避免使用宏(一个有价值的目标),您可以在标题中定义这些常量:

    namespace Namespace1
    {
        const int variable1 = 10;
        const int variable2 = 10;
    }
    

    这不会违反单一定义规则,因为 C++ 标准(甚至在 2003 年)允许通过使此类整数常量隐式具有内部链接,在多个翻译单元中定义它们。它们也是常量表达式,就像宏会产生一样。

    【讨论】:

    • 命名空间范围 const 变量是隐式静态的,因此不完全等同于原始 sn-p。
    • @PasserBy - 我希望它不等同。原来的sn-p会被初始化顺序破坏。
    • 我的意思是他们有不同的语义,以及回避惨败。
    • 既然“命名空间范围 const 变量是隐式静态的”,这是否意味着以下内容是等价的? namespace Namespace1 { const int variable1 = 10; }namespace Namespace1 { static const int variable1 = 10; }
    • @phön - 是的,这是一个棘手的问题,类似于max(variable1, variable2) comes to mind... 但我仍然认为这样的代码在实践中不太可能出现。无论如何,这不足以保证扩大答案。
    猜你喜欢
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 2015-01-07
    • 1970-01-01
    相关资源
    最近更新 更多