【问题标题】:C++ Dynamic initialization - across translation unitsC++ 动态初始化 - 跨翻译单元
【发布时间】:2014-03-14 16:47:47
【问题描述】:

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


3.6.2 非本地对象的初始化

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

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


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

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

谢谢!

[编辑:]

也许这可以归结为“它会发生”的解读为:

  1. 应该已经开始了
  2. 应已完成

【问题讨论】:

  • 这两种解释是什么?我真的只能看到一种可能的解释。知道另一个是什么会很有帮助。
  • 1:可能发生。 2:不可能发生。
  • 有些同事读这篇文章的方式就像“在课堂上使用”或“在外面使用”。
  • 但它说使用。不中使用或中使用。它涉及任何时候使用此 TU 中的函数或类,无论如何何时以及由谁使用。跨度>

标签: c++


【解决方案1】:

在动态初始化完成之前,从另一个翻译单元调用此类中的静态方法是否会发生(或不能)?

粗体部分很清楚,不是吗? 此类数据的初始化保证在第一次使用任何在其翻译单元中定义的函数或类之前发生。 调用函数的位置无关紧要。保证是在第一次使用翻译单元中的任何函数之前进行初始化。当然,它们可能被称为 另一个翻译单元,但这没有任何区别。在this翻译单元中定义的函数进入之前,必须已经进行了初始化。

换句话说,你是安全的。

...

假设单线程执行,即。 C++98 在多线程环境中不提供任何保证,因此对于线程应用程序,上述保证通常仅意味着初始化将由第一个线程执行以使用此翻译单元中的函数或类。然后你有一个竞争条件同时这个初始化正在执行,其他线程可能会碰到部分初始化的数据。

【讨论】:

  • 我了解您对比赛条件的描述。但是该标准根本没有对线程做出任何声明。那么如何确定可能会发生竞争条件。我会说它归结为如果您将“将要发生”读作“应该已经开始”或“应该已经完成​​”
  • @Adam 你不能确定出现竞争条件。这就是重点,标准没有说明线程,所以如果你有多个线程,所有的赌注都没有了。它只保证在纯顺序程序流中发生的事情(有效地,如果你有一个线程)。 然后 初始化将在第一次使用同一个 TU 中定义的任何函数之前完成。如果你有多个线程,那么任何事情都可能发生,我所描述的只是编译器的典型行为,不提供额外的保证
  • 在顺序执行中,“应该发生”意味着“应该已经开始”和“应该已经完成​​”。在非顺序执行(多线程)中,所有的赌注都没有。
  • 感谢 Jalf 这么详细地回答!
猜你喜欢
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多