Nifty / Schwarz计数器,标准兼容? [英] Nifty/Schwarz counter, standard compliant?

查看:141
本文介绍了Nifty / Schwarz计数器,标准兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天早上和一位同事讨论了静态变量初始化顺序。他提到了 Nifty / Schwarz计数器,我(有点)困惑。我理解它是如何工作的,但我不知道这是否,从技术上讲,符合标准。

I had a discussion this morning with a colleague about static variable initialization order. He mentioned the Nifty/Schwarz counter and I'm (sort of) puzzled. I understand how it works, but I'm not sure if this is, technically speaking, standard compliant.

假设3个以下文件(前两个是复制pasta 'd来自更多C ++成语):

Suppose the 3 following files (the first two are copy-pasta'd from More C++ Idioms):

//Stream.hpp
class StreamInitializer;

class Stream {
   friend class StreamInitializer;
 public:
   Stream () {
   // Constructor must be called before use.
   }
};
static class StreamInitializer {
  public:
    StreamInitializer ();
    ~StreamInitializer ();
} initializer; //Note object here in the header.







//Stream.cpp
static int nifty_counter = 0; 
// The counter is initialized at load-time i.e.,
// before any of the static objects are initialized.
StreamInitializer::StreamInitializer ()
{
  if (0 == nifty_counter++)
  {
    // Initialize Stream object's static members.
  }
}
StreamInitializer::~StreamInitializer ()
{
  if (0 == --nifty_counter)
  {
    // Clean-up.
  }
}







// Program.cpp
#include "Stream.hpp" // initializer increments "nifty_counter" from 0 to 1.

// Rest of code...
int main ( int, char ** ) { ... }

...这里就是问题!有两个静态变量: c $ ;


... and here lies the problem! There are two static variables:


  1. nifty_counter和

  2. initializerin Program.cpp

  1. "nifty_counter" in Stream.cpp; and
  2. "initializer" in Program.cpp.


b $ b

由于这两个变量恰好在两个不同的编译单元中,因此没有(AFAIK)官方保证 nifty_counter 初始化器的构造函数被调用之前初始化为0.

Since the two variables happen to be in two different compilation units, there is no (AFAIK) official guarantee that nifty_counter is initialized to 0 before initializer's constructor is called.

我可以想到两个快速解决方案为什么works:

I can think of two quick solutions as two why this "works":


  1. 现代编译器足够聪明,可以解析两个变量之间的依赖关系,并将代码放在可执行文件中的相应顺序中文件(极不可能);

  2. nifty_counter 实际上是在加载时间初始化的,就像文章所说,在可执行文件的数据段中,因此始终在运行任何代码之前(极有可能)初始化。

  1. modern compilers are smart enough to resolve the dependency between the two variables and place the code in the appropriate order in the executable file (highly unlikely);
  2. nifty_counter is actually initialized at "load-time" like the article says and its value is already placed in the "data segment" in the executable file, so it is always initialized "before any code is run" (highly likely).

这两个似乎在我看来,他们依赖于一些非官方,但可能的实现。

Both of these seem to me like they depend on some unofficial, yet possible implementation. Is this standard compliant or is this just "so likely to work" that we shouldn't worry about it?

推荐答案

我相信这个标准是合乎规范的,它保证工作。根据标准($ 3.6.2 / 1):具有静态存储持续时间(3.7.1)的对象在任何其他初始化之前应该被初始化(8.5)。

I believe it's guaranteed to work. According to the standard ($3.6.2/1): "Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place."

由于 nifty_counter 有静态存储持续时间,它会在创建 initializer 之前初始化,单位。

Since nifty_counter has static storage duration, it gets initialized before initializer is created, regardless of distribution across translation units.

编辑:在重读了相关部分后,考虑来自@Tadeusz Kopec的意见,我不太确定它是否已经定义好了, ,但是是非常微不足道的,以确保它是明确定义的:从 nifty_counter 的定义中删除初始化,因此它看起来像: / p>

After rereading the section in question, and considering input from @Tadeusz Kopec's comment, I'm less certain about whether it's well defined as it stands right now, but it is quite trivial to ensure that it is well-defined: remove the initialization from the definition of nifty_counter, so it looks like:

static int nifty_counter;

由于它有静态存储持续时间,所以即使不指定初始化,并删除初始化器可以消除对零初始化之后发生的任何其他初始化的任何疑问。

Since it has static storage duration, it will be zero-initialized, even without specifying an intializer -- and removing the initializer removes any doubt about any other initialization taking place after the zero-initialization.

这篇关于Nifty / Schwarz计数器,标准兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆