在同一编译单元内,C++标准规定静态初始化顺序是明确定义的——它是静态对象声明的顺序。但使用Sun Studio 12编译器时,我遇到了不直观的行为。我定义了一个模板类
请注意,
这是有问题的,因为 A 的构造函数使用了
以下是我的 main():
helper<T>
,其中包含一个类型为T
的静态成员_data
和一个使用_data
的静态成员函数foo
。在我的.cpp文件中,我把它放在main()之前。struct A { /* some definition */ };
typedef helper<int> s0;
typedef helper<A> s1;
请注意,
helper<int>
的 typedef 在 helper<A>
的前面。因此根据标准,我期望 helper<int>::_data
将会在 helper<A>::_data
之前构造(请记住,_data
是一个静态成员)。在 GCC 上,情况是这样的,但在 Sun 上不是这样。这是有问题的,因为 A 的构造函数使用了
helper<int>::_data
。我只有一个编译单元,并且没有更早的 helper<A>
实例化,所以我认为顺序应该是明确定义的。这是 Sun 编译器的 bug,还是 typedef 在技术上不构成定义/实例化?我的意思是,Sun 编译器的行为是否符合标准?以下是我的 main():
int main()
{
//Swapping the order of these has no effect on Sun
s0::foo();
s1::foo();
}
s0或s1没有其他用途。
s0::foo();
将隐式地立即实例化s0
。在这种情况下,从_data
引用的上下文取决于模板参数(毕竟它在模板的成员函数内部),因此_data
的实例化点与s0
的实例化点相同。但这也存在同样的问题:我不知道s0
和s1
的实例化顺序是什么。大多数情况下,这并没有什么区别... - Johannes Schaub - litbs0
和s1
的特化,它们根据它们的顺序具有不同的结果。 :( - Johannes Schaub - litb