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_point
的 documentation 明确给出了默认构造的 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 提供的 duration
s 保证具有带符号的积分 Rep
。如果您使用 class 类型 Rep
的自定义持续时间,那么无论定义如何 that,它将 default-initialized ] Rep
如下。
下面的 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_point
的 documentation 明确给出了默认构造的 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 提供的 duration
s 保证具有带符号的积分 Rep
。如果您使用 class 类型 Rep
的自定义持续时间,那么无论定义如何 that,它将 default-initialized ] Rep
如下。