何时初始化匿名命名空间数据?

时间:2008-12-01 14:48:08

标签: c++ namespaces

我一直在使用匿名命名空间来存储本地数据和函数,并想知道数据何时被初始化?是应用程序以与静态数据相同的方式启动还是依赖于编译器?例如:

// foo.cpp
#include "foo.h"

namespace {

const int SOME_VALUE = 42;

}

void foo::SomeFunc(int n)
{
    if (n == SOME_VALUE)
    {
        ...
    }
}

问题产生于使一些代码线程安全。在上面的例子中,我需要确保在第一次调用SomeFunc之前初始化SOME_VALUE

4 个答案:

答案 0 :(得分:6)

C ++标准, 3.6.2 / 1

  

零初始化和   用常量初始化   表达被统称为   静态初始化;所有其他   初始化是动态的   初始化。 POD类型的对象   (3.9)具有静态存储持续时间   用常量表达式初始化   (5.19)应在任何之前初始化   动态初始化发生。   对象具有静态存储持续时间   在命名空间作用域中定义的相同   翻译单位和动态   初始化应初始化   他们定义的顺序   出现在翻译单元中。

这实际上意味着,即使另一个翻译单元从外部调用SomeFunc函数,您的SOME_VALUE常量也将始终正确初始化,因为它是用常量表达式初始化的。

早期调用函数(在main之前)的唯一方法是使用动态初始化初始化对象。但到那时,根据标准报价,POD变量的初始化已经完成。

答案 1 :(得分:2)

在这种特殊情况下(一个const的全局变量),变量在编译时被“初始化”。

SOME_VALUE总是等于42。

事实上,大多数(所有?)编译器实际上都会编译它,好像它是硬编码的一样:

void foo::SomeFunc(int n)
{
    if (n == 42)
    {
        ...
    }
}

答案 2 :(得分:1)

命名空间与初始化时间无关。命名空间所做的就是更改属于它的名称。

答案 3 :(得分:0)

对于您实际问题的正确答案,请参阅Mathieu的回答。

但请注意,匿名命名空间不会影响全局和/或静态对象生命周期的开始和结束。换句话说,你就像使用简单的旧全局变量一样容易受到static initialization order问题的影响。

该链接还提供了一些避免问题的提示,使用“首次使用时构建”,在下一个主题中。