is std :: chrono :: duration по умолчанию инициализируется 0 - PullRequest
2 голосов
/ 14 марта 2020

Значение d ниже инициализированного (предположительно, до 0) или неинициализированного (небезопасного для чтения)?

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

Документация говорит, что по умолчанию используется конструктор по умолчанию.

Код библиотеки 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;

...

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

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

Rep должен быть арифметическим c типом или классом, имитирующим арифметический c тип.

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

constexpr duration() = default;

Вместе они говорят, что duration инициализирован по умолчанию как Rep is default-initialized

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

To default-initialize объект из тип 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 клиенты имеют выбор: неинициализированный или нулевой начальный. со стандартным значением duration s, которые гарантированно имеют подписанный интеграл Rep. Если вы используете пользовательскую длительность с типом класса Rep, тогда он будет инициализирован по умолчанию по определению , за которым следует Rep.

0 голосов
/ 14 марта 2020

Реализация duration не указана в стандарте, только интерфейс, который он должен предоставить. Конструктор по умолчанию явно не утверждает, что внутреннее состояние будет иметь какое-либо конкретное значение, поэтому нельзя предполагать, что созданная по умолчанию длительность будет инициализироваться нулем. Конкретная реализация может сделать это, и она может быть инициализирована нулями для некоторых типов, используемых для _Rep, но не для других.

Документация для time_point явно дает состояние для созданная по умолчанию точка времени, поэтому этот объект инициализируется нулями.

...