**Section:** 23.17.2 [time.syn] **Status:** New
**Submitter:** Andy Giese **Opened:** 2016-02-05 **Last modified:** 2016-05-08

**Priority: **4

**View all other** issues in [time.syn].

**View all issues with** New status.

**Discussion:**

Currently 23.17.2 [time.syn] states

// convenience typedefstypedef duration<signed integer type of at least 64 bits, nano> nanoseconds; typedef duration<signed integer type of at least 55 bits, micro> microseconds; typedef duration<signed integer type of at least 45 bits, milli> milliseconds; typedef duration<signed integer type of at least 35 bits> seconds; typedef duration<signed integer type of at least 29 bits, ratio< 60>> minutes; typedef duration<signed integer type of at least 23 bits, ratio<3600>> hours;

However, a `duration_cast<minutes>(seconds::max())` would cause overflow if the underlying signed integers
only met the minimums specified.

The standard should specify that implementations guarantee that a `duration_cast` from any smaller duration in
these "convenience typedefs" will not overflow any larger duration. That is, `hours` should be able to hold
the maximum of `minutes`, which should be able to hold the maximum of `seconds` and so on.

More formally, if the ratio `typedef A` and `typedef B` is `1:Y` where `Y > 1` (e.g.,
1 : 60 in case of `minutes` : `seconds`), then `#bits _{A}-1` must be at least

In the case of `minutes` : `seconds`, `X = 1`, `Y = 60`. Let
`#bits _{seconds} = 32`. Therefore:

`2`^{(#bitsseconds - 1)}= 2^{31}= 2147483648`ceil(log`_{2}(2^{31}/ 60) = 26`#bits`_{minutes}- 1 = 26`#bits`_{minutes}= 27

Therefore, a minimum of 27 bits would be needed to store `minutes` if 32 were used to store `seconds`.

I propose to change the definitions of the convenience typedefs as follows:

// convenience typedefstypedef duration<signed integer type of at least 64 bits, nano> nanoseconds; typedef duration<signed integer type of at least 55 bits, micro> microseconds; typedef duration<signed integer type of at least 46 bits, milli> milliseconds; typedef duration<signed integer type of at least 37 bits> seconds; typedef duration<signed integer type of at least 32 bits, ratio< 60>> minutes; typedef duration<signed integer type of at least 27 bits, ratio<3600>> hours;

These bits were chosen to satisfy the above formula. Note that
minimums only increased, so larger ranges could be held. A nice
outcome of this choice is that `minutes` does not go above 32 bits.

*[2016-04-23, Tim Song comments]*

The P/R of LWG 2592 doesn't fix the issue it wants to solve, because the actual underlying type will likely have more bits than the specified minimum.

Consider `seconds`, which the P/R requires to have at least 37 bits. On a typical system this implies
using a 64-bit integer. To ensure that casting from `seconds::max()` to `minutes` doesn't overflow
in such a system, it is necessary for the latter to have at least 59 bits (which means, in practice, 64 bits too),
not just 32 bits. Thus, just changing the minimum number of bits will not be able to provide the desired guarantee
that casting from a smaller unit to a larger one never overflow.

If such a guarantee is to be provided, it needs to be spelled out directly. Note that the difference here is 9 bits (for the 1000-fold case) and 5 bits (for the 60-fold case), which is less than the size difference between integer types on common systems, so such a requirement would effectively require those convenience typedefs to use the same underlying integer type.

**Proposed resolution:**

This wording is relative to N4567.

Change 23.17.2 [time.syn], header

`<chrono>`synopsis, as indicated[…]

*// convenience typedefs*typedef duration<*signed integer type of at least 64 bits*, nano> nanoseconds; typedef duration<*signed integer type of at least 55 bits*, micro> microseconds; typedef duration<*signed integer type of at least 46*, milli> milliseconds; typedef duration<~~45~~bits*signed integer type of at least 37*> seconds; typedef duration<~~35~~bits*signed integer type of at least 32*, ratio< 60>> minutes; typedef duration<~~29~~bits*signed integer type of at least 27*, ratio<3600>> hours; […]~~23~~bits