2008-12-01 98 views
4

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

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

namespace { 

const int SOME_VALUE = 42; 

} 

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

问题出现在某些代码是线程安全的。在上面的例子中,我需要确定SOME_VALUE是在第一次调用SomeFunc之前初始化的。

回答

6

C++标准,3.6.2/1

零初始化和 初始化以恒定 表达式统称 静态初始化;其他所有 初始化都是动态的 初始化。 POD类型对象 (3.9)静态存储持续时间 使用常量表达式 (5.19)初始化应在任何 动态初始化发生之前初始化。 对象与同一 翻译单元中命名空间范围定义的静态存储持续时间 和动态 初始化应 ,其中它们的定义 出现在翻译单元的次序进行初始化。

这实际上意味着,即使其他翻译单元调用外部您SomeFunc功能,您SOME_VALUE恒将始终正确初始化,因为它有常量表达式初始化。

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

2

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

SOME_VALUE总是等于42

事实上,大多数(?全部)编译器将实际编译这个就好像是硬编码:

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

为正确答案您的实际问题看Mathieu的回答。

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

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

1

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

相关问题