保证非odr使用的全局变量的延迟动态初始化

时间:2018-01-18 23:47:39

标签: c++ std c++17

考虑以下由两个TU组成的完整程序:

// 1.cpp
bool init() { /* ... */ }
const auto _{init()};

// 2.cpp
int main() {}

问题:是否有保证_在某些时候被初始化(我什么时候不在乎)?

现在考虑一个由TU组成的程序:

// 1.cpp
bool init() { /* ... */ }
const auto _{init()};
int main() {}

请注意_不是 odr-used

但是,在第二种情况下,main()可以说是odr-used,因为当程序运行时,它会被“实现”引用(有点)吗?

如果main()odr-used,这是否意味着_即使不是odr-used,也可以保证初始化?

编辑:

这是en.cppreference.com关于延迟动态初始化

的说法
  

如果给定的翻译单元没有使用变量或函数,   该翻译单元中定义的非局部变量可能永远不会   初始化(这模拟了按需动态库的行为)

在阅读我的两个例子时,你能否回答我的问题?

2 个答案:

答案 0 :(得分:4)

程序启动期间,所有翻译单元用静态存储持续时间整理所有对象以进行初始化,这应该是链接器的工作 - 然而,它比它更多,保证这些对象将在use of any function within that translation unit之前初始化。

  

basic.start.static/1:具有静态存储持续时间的变量初始化为a   计划启动的结果......

另见:

  

basic.stc.static/2:如果具有静态存储持续时间的变量具有初始化或a   具有副作用的破坏者,即使它也不会被消除   似乎没用了......

答案 1 :(得分:1)

保证对象_被初始化。根据[basic.start.static] / 1,

  

具有静态存储持续时间的变量由于程序启动而初始化。变量与   线程存储持续时间由于线程执行而初始化。

如果您想知道是否只能保证静态初始化发生,并且不能保证动态初始化,请参见[dcl.dcl] / 11,

  

定义会导致适当的存储量   保留和任何适当的初始化(11.6)。

因此,初始化程序{init()}的语义所需的所有初始化都应在对象_上执行。

像往常一样,as-if规则适用。如果init()具有任何可观察的行为,则必须发生此类行为。它有任何影响可观察行为的副作用,必须发生这种副作用。

_没有使用的事实是无关紧要的。关于main的切线也是无关紧要的。