静态初始化顺序失败

在他的Thinking in C++"(第 10 章)中,Eckel 描述了一种由 Jerry Schwarz 首创的技术来解决这场惨败.他说如果我们想将 x 初始化为 100 并将 y 初始化为 200 并在所有翻译单元之间共享它们,我们会创建一个如下所示的 Initializer.h:>

In his "Thinking in C++" (Chapter 10) Eckel describes a technique that was pioneered by Jerry Schwarz to solve the fiasco. He says that if we want to initialize x to 100 and y to 200 and share them among all translation units, we create an Initializer.h that looks like this:

extern int x;
extern int y;
class Initializer {
   static int initCount;
   // if (initCount++ == 0) x = 100 & y = 200
   /* ... */
};
static Initializer init;

在实现文件中我们有

#include "Initializer.h"
int x;
int y;
int Initializer::initCount;

并且 Eckel 说静态初始化(在实现文件中)将强制所有这些值为零".

and Eckel says that "static initialization (in implementation file) will force all these values to zero".

让我考虑以下情况:编译器在包含该标头的其他文件之后处理实现文件(这意味着 x 和 y 已在该其他文件中设置为 100 和 200).编译器看到int x,它会怎么做?它是否会将 x 和 y 设置为零以消除初始化和先前文件中所有可能的更改?但如果是这样,那么 initCount 也将被设置为零,从而破坏整个技术.

Let me consider the following case: the compiler processes the implementation file after some other file with that header included (it means that x and y have been already set to 100 and 200 in that other file). The compiler sees int x, so what will it do? Will it set x and y to zero eliminating initialization and all possible changes in previous files? But if it does, then initCount will also be set to zero, breaking down the whole technique.

推荐答案

但如果它是真的,并且编译器在另一个文件之后处理实现文件,那么它会将 x 和 y 设置为零以消除初始化和先前文件中所有可能的更改?

But if it is true, and the compiler handles the implementation file after some another file, than it will set x and y to zero eliminating initialization and all possible changes in previous files?

我不确定你的意思.如果在其他文件中定义了 xy,那么您就会发生链接器冲突,并且程序根本无法编译.

I'm not sure what you mean by this. If x and y are defined in other files, then you have a linker clash and the program simply won't compile.

如果 xy 和最重要的 Initializer::initCount 以这种方式实现,它们将在程序;它们实际上是全局的,将在程序开始时初始化为 0,之前 任何 Initializer 被构造(由于包含声明一个 static 该类的实例).static Initializer 的每个构造都会首先检查是否由于 if (initCount++ == 0) 等原因构造了任何其他 Initializer.

If x, y and most importantly Initializer::initCount are implemented in this way, there will be unique instances of them in the program; they are effectively global and will be initialized to 0 at program start, before any Initializer is constructed (due to inclusion of the header declaring a static instance of that class). Each construction of a static Initializer will first check whether any other Initializers have been constructed due to the if (initCount++ == 0) etc.

要运行的第一个 Initializer 构造函数(仍在进入 main 之前)将因此设置所有三个值.

The first Initializer ctor to run (still before entering main) will thus set all three values.

相关文章