This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
3090. What is §[time.duration.cons]p4's "no overflow is induced in the conversion" intended to mean?Section: 30.5.2 [time.duration.cons] Status: New Submitter: Richard Smith Opened: 2018-03-22 Last modified: 2020-09-12
Priority: 3
View all other issues in [time.duration.cons].
View all issues with New status.
Discussion:
30.5.2 [time.duration.cons] p4 says:
template<class Rep2, class Period2> constexpr duration(const duration<Rep2, Period2>& d);Remarks: This constructor shall not participate in overload resolution unless no overflow is induced in the conversion and
treat_as_floating_point_v<rep>
istrue
or bothratio_divide<Period2, period>::den
is 1 andtreat_as_floating_point_v<Rep2>
isfalse
.
with this example:
duration<int, milli> ms(3); duration<int, micro> us = ms; // OK duration<int, milli> ms2 = us; // error
It's unclear to me what "no overflow is induced in the conversion" means in the above. What happens here:
duration<int, milli> ms(INT_MAX); duration<int, micro> us = ms; // ???
An overflow is clearly induced in the conversion here: internally, we'll multiply INT_MAX
by 1000. But that cannot be determined statically (in general), and so can't affect the result of overload resolution.
Rep2
is no larger than Rep
? (If so, what happens on overflow? Undefined behavior?) It has been pointed out by Howard Hinnant:
This refers to the compile-time conversion factor to convertPeriod2
toPeriod
. If that conversion factor is not representable as a (reduced)ratio<N, D>
, then the constructor is SFINAE'd out. This might happen (for example) converting years to picoseconds.
I would not have guessed that from the wording. Maybe replacing "no overflow is induced in the conversion" with "the result of ratio_divide<Period2, Period>
is representable as a ratio
" or similar would help?
[2018-06-18 after reflector discussion]
Priority set to 3
[2020-09-12 Jonathan adds a proposed resolution]
Since the result of the ratio_divide
has to be a ratio
, if it's not representable then the result simply isn't a valid type. Implementations are not required to make ratio_divide
SFINAE-friendly to implement this constraint. They can perform the equivalent calculations to check if they would overflow, without actually using ratio_divide
.
Proposed resolution:
This wording is relative to N4861.
Modify 30.5.2 [time.duration.cons] as indicated:
template<class Rep2, class Period2> constexpr duration(const duration<Rep2, Period2>& d);
-3- Constraints: is_convertible_v<const Rep2&, rep>
is true
. ratio_divide<typename Period2::type, period>
is a valid ratio
specialization. Either:
treat_as_floating_point_v<rep>
is true
; orratio_divide<Period2, period>::den
is 1
and treat_as_floating_point_v<Rep2>
is false
.No overflow is induced in the conversion and treat_as_floating_point_v<rep>
is true
or both ratio_divide<Period2, period>::den
is 1
and treat_as_floating_point_v<Rep2>
is false
. [Note: This requirement prevents implicit truncation error s when converting between integral-based duration
types. Such a construction could easily lead to confusion about the value of the duration
. — end note]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4