Created on 2014-05-16.00:00:00 last changed 2 weeks ago
Proposed resolution:
This wording is relative to N5046.
Three options are presented, choose only one.Option A
Modify [time.duration.literals] as indicated:
-1- This subclause describes literal suffixes for constructing duration literals. The suffixes `h`, `min`, `s`, `ms`, `us`, `ns` denote duration values of the corresponding types `hours`, `minutes`, `seconds`, `milliseconds`, `microseconds`, and `nanoseconds` respectively if they are applied to integer-literals.
-2- If any of these suffixes
areis applied to a floating-point-literal the result is a `chrono::duration` literal with an unspecified floating-point representation.-3- If any of these suffixes
areis applied to an integer-literal and the parameter cannot be represented in the `rep` type of the return type,the resulting `chrono::duration` value cannot be represented in the result type because of overflow,the program is ill-formed.-4- [Example 1: The following code shows some duration literals.
— end example]using namespace std::chrono_literals; auto constexpr aday=24h; auto constexpr lesson=45min; auto constexpr halfanhour=0.5h;constexprconsteval chrono::hours operator""h(unsigned long long hours);constexprconsteval chrono::duration<unspecified, ratio<3600, 1>> operator""h(long double hours);-5- Returns: A `duration`
literalvalue representing `hours` hours.constexprconsteval chrono::minutes operator""min(unsigned long long minutes);constexprconsteval chrono::duration<unspecified, ratio<60, 1>> operator""min(long double minutes);-6- Returns: A `duration`
literalvalue representing `minutes` minutes.constexprconsteval chrono::seconds operator""s(unsigned long long seconds);constexprconsteval chrono::duration<unspecified> operator""s(long double seconds);-7- Returns: A `duration`
literalvalue representing `seconds` seconds.-8- [Note 1: The same suffix `s` is used for `basic_string` but there is no conflict, since duration suffixes apply to numbers and string literal suffixes apply to character array literals. — end note]
constexprconsteval chrono::milliseconds operator""ms(unsigned long long msec);constexprconsteval chrono::duration<unspecified, milli> operator""ms(long double msec);-9- Returns: A `duration`
literalvalue representing `msec` milliseconds.constexprconsteval chrono::microseconds operator""us(unsigned long long usec);constexprconsteval chrono::duration<unspecified, micro> operator""us(long double usec);-10- Returns: A `duration`
literalvalue representing `usec` microseconds.constexprconsteval chrono::nanoseconds operator""ns(unsigned long long nsec);constexprconsteval chrono::duration<unspecified, nano> operator""ns(long double nsec);-11- Returns: A `duration`
literalvalue representing `nsec` nanoseconds.
Add [diff.cpp26.duration] to Annex C:
C.1.? Clause [time]: Time library
Affected subclause: [time.duration.literals]
Change: Literal operators for `duration` literals are immediate functions. Rationale: Allow checking for overflow. Effect on original feature: Valid C++ 2026 code that used function call syntax and non-constant arguments to create duration literals is ill-formed in this document.[Example ?:
— end example]int n = 60; auto t = std::chrono::literals::operator""s(n); // ill-formed; previously well-formed
Modify [time.duration.literals] as indicated:
-1- This subclause describes literal suffixes for constructing duration literals. The suffixes `h`, `min`, `s`, `ms`, `us`, `ns` denote duration values of the corresponding types `hours`, `minutes`, `seconds`, `milliseconds`, `microseconds`, and `nanoseconds` respectively if they are applied to integer-literals.
-2- If any of these suffixes
areis applied to a floating-point-literal the result is a `chrono::duration` literal with an unspecified floating-point representation.-3- If any of these suffixes
areis applied to an integer-literal and the parameter cannot be represented in the `rep` type of the return type,the resulting `chrono::duration` value cannot be represented in the result type because of overflow,the program is ill-formed.-?- It is unspecified whether the literal operators below are usable only as the suffix of a user-defined-literal ([lex.ext]), or whether they can also be called using function call notation. If they can be called using function call notation, using `unsigned long long` parameters that cannot be represented in the `rep` type of the return type is ill-formed, no diagnostic required.
Option B should also do the "`duration`literalvalue" drive-by fix, and probably update Annex C as well.
Modify [time.duration.literals] as indicated:
-1- This subclause describes literal suffixes for constructing duration literals. The suffixes `h`, `min`, `s`, `ms`, `us`, `ns` denote duration values of the corresponding types `hours`, `minutes`, `seconds`, `milliseconds`, `microseconds`, and `nanoseconds` respectively if they are applied to integer-literals.
-2- If any of these suffixes
areis applied to a floating-point-literal the result is a `chrono::duration` literal with an unspecified floating-point representation.
-3- If any of these suffixes are applied to an integer-literal and the resulting `chrono::duration` value cannot be represented in the result type because of overflow, the program is ill-formed.
[ 2026-06-16; Jonathan adds wording. ]
The library has no way to distinguish the case where a suffix is "applied to an integer literal", as opposed to using function call notation like `operator""s(123)`. There is never overflow, because converting `unsigned long long` to a `rep` such as `signed long long` is always well-formed, just not value-preserving. Unless it is used as a constant subexpression, a user-defined-literal such as `123s` is not constant evaluated, so in general checking the value at compile-time is unimplementable.
If we made these operators `consteval` then using them as the suffix of a user-defined-literal would always be a constant expression. It would make it ill-formed to call `operator""s(some_variable)` but I consider that perfectly acceptable. Such uses are absurd, and the existing wording is all specified in terms of suffixes anyway, not in terms of function calls to those operators. P3931R0 proposes making these (and other literal operators) consteval, which would resolve this issue by making it implementable.
Alternatively, we could permit the integral literal operators to be implemented
as literal operator templates, i.e. template<char... Digits>,
as this makes it possible to check for overflow. This is what libstdc++ has
done since the duration literals were first implemented.
Alternatively, we could just remove the rule saying that overflow is detected. Neither libc++ nor MSVC implements the overflow check, so if it was a problem that affects many users we'd have heard about it.
[ Urbana 2014-11-07: Move to Open ]
[time.duration.literals] p3 says:
If any of these suffixes are applied to an integer literal and the resulting chrono::duration value cannot be represented in the result type because of overflow, the program is ill-formed.
Ill-formed requires a diagnostic at compile-time, but there is no way to detect the overflow from unsigned long long to the signed duration<>::rep type.
Overflow could be detected if the duration integer literals were literal operator templates, otherwise overflow can either be undefined or a run-time error, not ill-formed.| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2026-06-16 11:40:48 | admin | set | messages: + msg16479 |
| 2026-06-16 11:40:48 | admin | set | messages: + msg16478 |
| 2014-11-08 16:43:57 | admin | set | messages: + msg7173 |
| 2014-11-08 16:43:57 | admin | set | status: new -> open |
| 2014-05-16 00:00:00 | admin | create | |