是 std::chrono::duration 默认初始化为 0

bil*_*ill 5 c++ c++11 c++-chrono

下面的 d 值是已初始化(大概为 0)还是未初始化(读取不安全)?

std::chrono::system_clock::duration d;
Run Code Online (Sandbox Code Playgroud)

文档说默认构造函数是默认的。

下面的 std 库代码似乎表明它是未初始化的,因为最终 int64_t 是一个标量,而标量的默认初始化是没有初始化。

我的理解正确吗?std::chrono::system_clock::time_point初始化为 0 时,它让我吃惊。

    struct system_clock
    {
      typedef chrono::nanoseconds                   duration;
...
    /// nanoseconds
    typedef duration<int64_t, nano>         nanoseconds;

...
    template<typename _Rep, typename _Period>
      struct duration
      {
    typedef _Rep                        rep;
    typedef _Period                     period;

...
Run Code Online (Sandbox Code Playgroud)

How*_*ant 4

http://eel.is/c++draft/time.duration#2

Rep应是算术类型或模拟算术类型的类。

http://eel.is/c++draft/time.duration#1

constexpr duration() = default;

这些一起说duration默认初始化的,就像默认初始化Rep一样

http://eel.is/c++draft/dcl.init#7

默认初始化类型的对象T意味着:

  • 如果T是(可能是 cv 限定的)类类型 ([class]),则考虑构造函数。枚举适用的构造函数 ([over.match.ctor]),并通过重载决策 ([over.match]) 选择最适合初始化程序 () 的构造函数。使用空参数列表调用如此选择的构造函数来初始化对象。(7.2)

  • 如果T是数组类型,则每个元素都默认初始化。

  • 否则,不执行初始化。

因此:

seconds s;  // no initialization.
Run Code Online (Sandbox Code Playgroud)

然而,这个:

seconds s{};  // zero-initialize
Run Code Online (Sandbox Code Playgroud)

进行值初始化,对于标量来说是零初始化

http://eel.is/c++draft/dcl.init#list-3.11

否则,如果初始值设定项列表没有元素,则对该对象进行值初始化。

http://eel.is/c++draft/dcl.init#8

对 T 类型的对象进行值初始化意味着:

  • 如果 T 是(可能是 cv 限定的)类类型 ([class]),那么...
  • 否则,该对象将被零初始化。

http://eel.is/c++draft/dcl.init#6

对 T 类型的对象或引用进行零初始化意味着:

  • 如果 T 是标量类型,则该对象被初始化为通过将整数文字 0(零)转换为 T 获得的值;90

因此,duration客户可以选择未初始化或零初始化,并duration保证 std 提供的 s 具有带符号的积分Rep。如果您在类 type 中使用自定义持续时间Rep,那么它将通过后面任何定义进行默认初始化 Rep