gpt4 book ai didi

c++ - Nifty/Schwarz 计数器,符合标准?

转载 作者:IT老高 更新时间:2023-10-28 22:19:24 26 4
gpt4 key购买 nike

今天早上我和一位同事讨论了静态变量初始化顺序。他提到了Nifty/Schwarz counter我(有点)困惑。我了解它的工作原理,但我不确定这在技术上是否符合标准。

假设以下 3 个文件(前两个是从 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 ** ) { ... }

...问题就在这里!有两个静态变量:

  1. Stream.cpp 中的“nifty_counter” ;和
  2. Program.cpp 中的“初始化程序” .

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

我可以将两个快速解决方案视为“有效”的两个原因:

  1. 现代编译器足够聪明,可以解决两个变量之间的依赖关系,并将代码以适当的顺序放置在可执行文件中(不太可能);
  2. nifty_counter实际上就像文章所说的那样在“加载时”初始化,并且它的值已经放在可执行文件的“数据段”中,所以它总是在“任何代码运行之前”初始化(很有可能)。

在我看来,这两者都依赖于一些非官方但可能的实现。这个标准是否符合标准,还是只是“很可能起作用”以至于我们不应该担心它?

最佳答案

我相信它一定会奏效。根据标准 ($3.6.2/1):“在进行任何其他初始化之前,具有静态存储持续时间 (3.7.1) 的对象应进行零初始化 (8.5)。”

由于 nifty_counter 具有静态存储持续时间,因此它会在创建 initializer 之前进行初始化,而与翻译单元之间的分布无关。

编辑:重新阅读相关部分并考虑@Tadeusz Kopec 评论的输入后,我不太确定它是否像现在这样定义良好,但它对于确保它是明确定义的:从 nifty_counter 的定义中删除初始化,所以它看起来像:

static int nifty_counter;

由于它具有静态存储持续时间,因此即使没有指定初始化程序,它也会被零初始化 - 删除初始化程序可以消除对在零初始化之后发生的任何其他初始化的任何疑问。

关于c++ - Nifty/Schwarz 计数器,符合标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5622574/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com