C++ C++;动态初始化-跨翻译单元

C++ C++;动态初始化-跨翻译单元,c++,C++,C++98语言标准规定: (我的重点) 3.6.2非局部对象的初始化 1英镑 [...] 零初始化 使用常量表达式的初始化和 称为静态初始化;所有其他初始化都是动态初始化。 [……] 3英镑 [...] 它是实现定义的 命名空间范围的对象的动态初始化(8.5、9.4、12.1、12.6.1)是否在main的第一条语句之前完成。如果初始化延迟到main的第一个语句之后的某个时间点,它应在与要初始化的对象在同一翻译单元中定义的任何函数或对象首次使用之前发生。 [……] 在我的办公室里,我们有两种

C++98语言标准规定: (我的重点)


3.6.2非局部对象的初始化

1英镑 [...] 零初始化 使用常量表达式的初始化和 称为静态初始化;所有其他初始化都是动态初始化。 [……]

3英镑 [...] 它是实现定义的 命名空间范围的对象的动态初始化(8.5、9.4、12.1、12.6.1)是否在main的第一条语句之前完成。如果初始化延迟到main的第一个语句之后的某个时间点,它应在与要初始化的对象在同一翻译单元中定义的任何函数或对象首次使用之前发生。 [……]


在我的办公室里,我们有两种对黑体字段落的解释

我的问题是:有一个类有一大堆静态方法和动态初始化的静态数据成员。在动态初始化完成之前,该类中的静态方法是否会从另一个翻译单元调用

谢谢

[编辑:] 也许这可以归结为对“它将发生”的解读:

  • 应该已经开始了
  • 应该已经完成了
  • 在动态初始化完成之前,这个类中的静态方法会不会从另一个翻译单元调用

    粗体的段落很清楚,不是吗? 此类数据的初始化保证在首次使用其翻译单元中定义的任何函数或类之前发生。从哪里调用函数并不重要。保证在第一次使用翻译单元中的任何函数之前进行初始化。当然,它们可以从另一个翻译单元调用,但这没有任何区别。在输入此翻译单元中定义的功能之前,必须执行初始化

    换句话说,你是安全的


    假设单线程执行,也就是说。C++98在多线程环境中不提供任何保证,因此对于线程应用程序,上述保证通常只意味着将由第一个线程执行初始化,以使用此转换单元中的函数或类。然后,在执行此初始化时,您会遇到一个争用条件,其他线程可能会碰到部分初始化的数据。

    这两种解释是什么?我真的只能看到一种可能的解释。知道另一个是什么会有帮助的。1:可能发生。2:不可能。一些同事读到这句话的方式就像“在课堂内使用”或“从外部使用”。但它说的是使用。不在内部使用或从外部使用。它谈论的是任何时候使用这个TU中的函数或类,不管它是如何使用的,何时使用的,由谁使用的。我理解你对竞争条件的描述。但该标准根本没有对线程做出任何声明。那么,我们如何才能确定可能会发生竞争情况呢。我会说,如果你把“将要发生”理解为“将要开始”或“将要完成”@Adam,你就不能确定比赛条件是否发生了。这就是问题所在,标准中没有提到线程,所以如果你有多个线程,所有的赌注都是无效的。它只保证在纯粹的顺序程序流中发生的事情(如果您只有一个线程,那么就可以有效地保证)。然后初始化将在首次使用同一TU中定义的任何函数之前完成。如果您有多个线程,那么任何事情都可能发生,我所描述的只是编译器上的典型行为,不提供额外的保证在顺序执行中,“应发生”意味着“应已开始”和“应该已经完成了”。在非顺序执行(多线程)中,所有赌注都被取消。感谢Jalf,感谢您费心回答这么多细节!