Date: Wed, 3 Apr 2024 11:44:07 +0100
On Wed, 3 Apr 2024 at 10:45, Federico Kircheis via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Hello,
>
>
> I have a question about the default constructor of std::chrono::duration
>
> For example std::chrono::duration::seconds
>
> According to the standard, it has a default constructor, but the
> standard does not specify to what value a default constructed duration
> is set to object.
>
>
> I found
>
>
> https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/OcGX7Yj3meI
>
> that argues that having an uninitialized duration is by design, which
> follows the question if the standard be more explicit?
>
> For me (and many colleagues) it was a surprise, as the presence of a
> default constructor hinted that the type would be initialized.
>
No, it behaves like its rep type. If that's an integral type, then default
initialization of a duration acts just like default initialization of its
rep type: no initialization is performed.
Value initialization will initialize it though, e.g. chrono::seconds{}.
> I find the rationale weak, as I would have thought not having a default
> constructor would have made much more sense, but it is obviously to late
> to change that.
>
For the common durations using an integral rep, default initialization
creates an uninitialized value. But for a custom rep type, the default
constructor could create an invalid value.
e.g.
struct drep {
double val = std::numeric_limits<double>::quiet_NaN();
// ...
};
std::chrono::duration<drep> d; // nan value
std::chrono::duration<drep> d0 = d.zero(); // zero value
I think there's a good argument for saying that the default constructor
should have been specified to value-initialize its rep member. That would
still allow the custom behaviour shown above to work, as the value init'd
'drep' type would still have a NaN value. But changing that would change
the result of is_trivial_v<chrono::seconds> etc. (they would still be
trivially copyable though).
std-proposals_at_[hidden]> wrote:
> Hello,
>
>
> I have a question about the default constructor of std::chrono::duration
>
> For example std::chrono::duration::seconds
>
> According to the standard, it has a default constructor, but the
> standard does not specify to what value a default constructed duration
> is set to object.
>
>
> I found
>
>
> https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/OcGX7Yj3meI
>
> that argues that having an uninitialized duration is by design, which
> follows the question if the standard be more explicit?
>
> For me (and many colleagues) it was a surprise, as the presence of a
> default constructor hinted that the type would be initialized.
>
No, it behaves like its rep type. If that's an integral type, then default
initialization of a duration acts just like default initialization of its
rep type: no initialization is performed.
Value initialization will initialize it though, e.g. chrono::seconds{}.
> I find the rationale weak, as I would have thought not having a default
> constructor would have made much more sense, but it is obviously to late
> to change that.
>
For the common durations using an integral rep, default initialization
creates an uninitialized value. But for a custom rep type, the default
constructor could create an invalid value.
e.g.
struct drep {
double val = std::numeric_limits<double>::quiet_NaN();
// ...
};
std::chrono::duration<drep> d; // nan value
std::chrono::duration<drep> d0 = d.zero(); // zero value
I think there's a good argument for saying that the default constructor
should have been specified to value-initialize its rep member. That would
still allow the custom behaviour shown above to work, as the value init'd
'drep' type would still have a NaN value. But changing that would change
the result of is_trivial_v<chrono::seconds> etc. (they would still be
trivially copyable though).
Received on 2024-04-03 10:45:25