Should constructors on std::chrono::...::time_point be noexcept? (Or why aren't they?)

atomic, c++, c++-chrono, noexcept

Solution

In my humble opinion, they should be conditionally `noexcept`. And to describe the correct condition, we need to back up and discuss the constructors of `duration`.

First the special constructors: default and copy.

These constructors are correctly specified with `= default`. That means that if the underlying `rep` has special `noexcept` constructors then the `duration` will too. That is exactly what we want.

Now what about:

template <class Rep2>
   constexpr explicit duration(const Rep2& r);
template <class Rep2, class Period2>
   constexpr duration(const duration<Rep2, Period2>& d);

These are not currently `noexcept`, but we would like for them to be if the constructions that they call are `noexcept`. For example:

template <class Rep2>
   constexpr explicit duration(const Rep2& r)
       noexcept(is_nothrow_constructible<rep, Rep2 const&>{});
template <class Rep2, class Period2>
   constexpr duration(const duration<Rep2, Period2>& d)
       noexcept(noexcept(is_nothrow_copy_constructible<rep>{}) &&
                noexcept(std::chrono::duration_cast<duration>(d)));

This means that they will be noexcept for the common use cases. However if you create a `Rep` that is an arithmetic emulator that might (for example) throw on overflow, then these constructors will correctly not be `noexcept`.

To make these constructors actually work, the member function `count()` needs to be conditionally `noexcept`, and the function `duration_cast` needs to be made conditionally `noexcept`.

Now (and only now) one can start to tackle the `time_point` constructors with similar rigor.

This is all doable. I've just prototyped it to confirm that I'm actually giving good information in this answer. However to make this all std, one has to:

- Implement and fully test the whole thing.

- Write a proposal that convincingly argues that this is implementable, and valuable to the clients.

- Attend standards meetings and present this proposal, and be convincing.

- When the committee finds holes in your argument (and they will), fix the implementation, fix the proposal, and go back to step 3.

- Continue with steps 3 and 4 until the committee is so sick of hearing from you that they give in and vote it into a draft standard.

- Wait for the draft to become an official standard, and protect the proposal from being voted out of the standard while waiting.

To date the committee has applied conditional `noexcept` to functions exceedingly sparingly.

The answer to the question in the title is simply:

No one has put all this work into it. However I would encourage people to do so. I believe this would benefit the clients of `<chrono>`.

Problem

I encountered this problem trying to hold on to an atomic time_point, see (atomic requires noexcept default constructor if default constructor available): http://cplusplus.github.io/LWG/lwg-active.html#2165 The simple problem is std::atomic or similar will fail to compile under the current std. Considering the std::chrono::clock_type::now() s are noexcept. It seems bizarre that the timepoints themselves are not.

Original source