【问题标题】:is std::chrono::duration default initialized to 0是 std::chrono::duration 默认初始化为 0
【发布时间】:2020-03-14 19:12:29
【问题描述】:

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

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

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

下面的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;

...

【问题讨论】:

    标签: c++ c++11 chrono


    【解决方案1】:

    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.
    

    但是,这个:

    seconds s{};  // zero-initialize
    

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

    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 客户可以选择未初始化或零初始化,标准提供的durations 保证有一个有符号整数Rep。如果您使用具有类类型 Rep 的自定义持续时间,那么它将被 default-initialized 通过任何定义 Rep 遵循。

    【讨论】:

    • 但是 std::chrono::seconds 是一个类类型。您省略了第一个项目符号发生的文本,这似乎是相关的:(我研究过,chrono::seconds 的零值初始化似乎需要“秒”的零初始化。但这是否意味着 Rep 对象的零初始化? 为此,Rep 对象需要是一个非静态数据成员。这是明确指定的吗?库规范说“实现可以使用任何提供等效可观察行为的技术。”对于“仅展示”成员。所以这似乎不能保证?
    • 你引用的话证明了我的论点。如果实现具有与仅展示数据成员指定的行为不同的可观察行为,则它不符合要求。供应商必须支持具有 Rep 数据成员的显式默认默认构造函数的可观察行为。供应商可能会改变实现方式,比如将数据成员名称拼写为 rep_ 以外的其他名称。
    • 谢谢,我误解了“等效可观察行为”的含义。我认为这意味着根据所有非“仅展示”规则的行为。现在我很清楚了。最后,chrono::seconds 的行为类似于原始算术类型,非常有用。
    • 嗯,这意味着我们不应该通过值传递std::chrono::durations?
    • 如果您还遵循不按值传递int 的准则。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2020-10-03
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多