gcc是否对静态成员初始化时间有任何保证,特别是关于模板类?
我想知道在多个编译单元实例化类PWrap_T
之前main()
,是否可以保证静态成员()将被初始化.在main的开头尝试手动触摸每个编译单元的符号是不切实际的,但我不清楚其他任何东西是否有效.
我已经用bar()
不同单位的方法进行了测试,并且总是得到了预期的结果,但是我需要知道什么时候/如果gcc会将地毯拉出来以及它是否可以预防.
此外,在库完成加载之前,是否会初始化DSO中的所有静态成员?
#include#include struct P; inline std::deque &ps() { static std::deque
d; return d; } void dump(); struct P { P(int id, char const *i) : id_(id), inf_(i) { ps().push_back(this); } void doStuff() { std::cout << id_ << " (" << inf_ << ")" << std::endl; } int const id_; char const *const inf_; }; template
struct PWrap_T { static P p_s; }; // *** Can I guarantee this is done before main()? *** template P PWrap_T ::p_s(T::id(), T::desc()); #define PP(ID, DESC, NAME) /* semicolon must follow! */ \ struct ppdef_##NAME { \ constexpr static int id() { return ID; } \ constexpr static char const *desc() { return DESC; } \ }; \ PWrap_T const NAME // In a compilation unit apart from the template/macro header. void dump() { std::cout << "["; for (P *pp : ps()) { std::cout << " " << pp->id_ << ":" << pp->inf_; } std::cout << " ]" << std::endl; } // In some compilation unit. void bar(int cnt) { for (int i = 0; i < cnt; ++i) { PP(2, "description", pp); pp.p_s.doStuff(); } } int main() { dump(); PP(3, "another", pp2); bar(5); pp2.p_s.doStuff(); }
(C++11§3.6.2/ 4 - [basic.start.init] :)
实现定义了具有静态存储持续时间的非局部变量的动态初始化是否在main的第一个语句之前完成.如果初始化延迟到第一个main语句之后的某个时间点,则应该在与要初始化的变量相同的转换单元中定义的任何函数或变量的第一个odr-use(3.2)之前发生.
...具有静态存储持续时间且具有副作用初始化的非局部变量必须初始化,即使它没有使用(3.2,3.7.1).
此外,尝试__attribute__ ((init_priority(int)))
或__attribute__ ((constructor))
模板成员的初始化产生warning: attributes after parenthesized initializer ignored
,我知道没有其他关于静态初始化的技巧.
在此先感谢任何能给我答案的人!