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

is std::chrono::duration default initialized to 0

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

std::chrono::system_clock::duration d;

Documentation 表示默认构造函数是默认的。

下面的标准库代码似乎表明它未初始化,因为最终 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;

...

duration 的实现在标准中没有指定,只有它必须提供的接口。默认构造函数没有明确声明内部状态将具有任何特定值,因此您不能假设默认构造的持续时间将被零初始化。一个特定的实现可能会这样做,并且对于某些用于 _Rep 但不是其他类型的类型,它可能是零初始化的。

time_pointdocumentation 明确给出了默认构造的 time_point 的状态,这就是该对象被零初始化的原因。

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

Rep shall be an arithmetic type or a class emulating an arithmetic type.

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

constexpr duration() = default;

一起说 duration默认初始化的 因为 Rep默认初始化的

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

To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type ([class]), constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object. (7.2)

  • If T is an array type, each element is default-initialized.

  • Otherwise, no initialization is performed.

因此:

seconds s;  // no initialization.

然而,这:

seconds s{};  // zero-initialize

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

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

Otherwise, if the initializer list has no elements, the object is value-initialized.

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

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type ([class]), then ...
  • otherwise, the object is zero-initialized.

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

To zero-initialize an object or reference of type T means:

  • if T is a scalar type, the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;90

因此 duration 客户端可以选择未初始化或零初始化,std 提供的 durations 保证具有带符号的积分 Rep。如果您使用 class 类型 Rep 的自定义持续时间,那么无论定义如何 that,它将 default-initialized ] Rep 如下。