【问题标题】:Static initialization of local variables局部变量的静态初始化
【发布时间】:2015-06-25 04:57:47
【问题描述】:

来自 Scott Meyers Effective C++

如果你从不调用模拟非本地静态对象的函数,你 永远不会产生构建和破坏对象的成本, 对于真正的非本地静态对象来说,这是不能说的。

功能:

FileSystem& tfs()
{ 
    static FileSystem fs;
    return fs; 
}

但标准说:

使用静态的块范围实体的常量初始化 (3.6.2) 存储持续时间(如果适用)在其块被执行之前执行 第一次进入。 允许提前执行 使用静态或线程初始化其他块范围变量 在与实现相同的条件下的存储持续时间 允许用静态或线程静态初始化变量 命名空间范围内的存储持续时间 (3.6.2)。

这意味着即使我们不调用函数tfs(),我们也无法确定fs 变量是否已初始化。因为允许实现对具有静态存储持续时间的变量执行早期初始化。

谁是对的,或者我错过了什么?

【问题讨论】:

  • 如有疑问,请相信规范。 Effective C++ 于 1992 年发布,也许事情已经发生了变化。

标签: c++ initialization


【解决方案1】:

Constant initialization 描述了可以在编译时确定的初始化。

只有在 C++11 及更高版本中,才能考虑具有非平凡构造函数的类型:

如果构造函数是constexpr

在“Effective C++”中,Meyers 将您问题中的类描述为:

class FileSystem {...};

这意味着在 C++ 标准正确的情况下,“有效 C++”也可以保持正确即使在 C++11 之后,只要为 FileSystem 提供的构造函数不是 constexpr .

【讨论】:

  • 在编译时谈论初始化真的正确吗?我的意思是,在程序启动时执行常量初始化(或推迟到main() 的某些语句)。
  • 还有一件事,constexpr ontructor 将保证初始化是一个 const 初始化。所以会在第一次进入block的时候执行?
  • @Stella - constexpr 构造函数允许在编译时知道值,但它也要求所有参数也都是常量表达式。无论如何,如果编译器可以在可执行文件中包含已经构建的对象,则初始化没有运行时成本。
猜你喜欢
  • 1970-01-01
  • 2013-07-21
  • 2019-04-23
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
相关资源
最近更新 更多