[Development] <chrono> first (was: Re: C++20 @ Qt)
Marc Mutz
marc.mutz at qt.io
Mon Jan 23 14:06:13 CET 2023
Hi,
TL;DR:
- don't use qin64 for durations
- use QDeadlineTimer for timeouts
- use chrono::{milli,micro,nano,}seconds for everything that doesn't have Forever state
- don't implement chrono via integer overloads, do it the other way around
Not really C++20, rather C++11, but let's keep the C++ stuff together.
Since 2018, in QTBUG-67383, we have users complaining about the limited
range of int milliseconds arguments:
> Now QTimer::start(int msec) accepts only int values which corresponds
> to ~ 24 days as maximum time interval.
Instead of changing to qint64 timeouts, as suggested, we should use
chrono types. Here's why:
- we do have QDeadlineTimer, which implicitly converts from chrono
types, but
- it has a Forever state, which is meaningful for timeouts, but not
for intervals (QTimer with Forever interval?).
- it's name doesn't exactly lend itself for use in APIs (why pass a
timer to a timer?)
- it always has nanosecond resolution. Most of our APIs have
millisecond resolution. Unless we want to change them all to ns
resolution, any function using QDT must document the real
granularity of the duration, and the rounding mode from ns. In
contrast, passing 1ns to a function taking chrono::milliseconds
simply fails to compile,forcing the caller to be explicit about what
he wants (chrono::floor, chrono::ceil, duration_cast, ...).
- we do support chrono types in many APIs, and we want to support them
in all APIs that deal with duration, as 1s is just so much more expressive
than '1000'. The integer-based APIs should be considered legacy
support. At some point, we might want to deprecate them, and then the
chrono overloads become the main implementation, anyway, so we might
just go there directly.
- if we take qint64, then internally have to construct a chrono type
from it, it means Qt code is responsible for checking for overflow
(chrono::milliseconds need not support the full 64-bit range),
creating an artificial error state that wouldn't exist if we only
accepted chrono types.
- if we take a chrono type, then shoehorn it through a legacy int
overload, we lose the range provided by the chrono types and
requested by users
So, chrono types are
- more future-proof
- safer (both as in less possible errors in the implementation, as well
as more type-safe in the caller)
- self-explanatory (w.r.t. granularity)
- more expressive
So, I suggest to port all duration-related APIs to <chrono>, and make
<chrono> the primary implementation, not vice versa. In any case, ndo ot
add 64-bit timeouts (ns granularity like QDeeadlineTimer is ok, because
std::chrono::nanoseconds has at least a 64-bit representation). Do not
add new integer-based duration properties. Use QDeadlineTimer if
'Forever' is a valid value (e.g. timeouts).
There's no rush, we need to get the plumbing in QtCore right, first.
Comments?
Thanks,
Marc
--
Marc Mutz <marc.mutz at qt.io>
Principal Software Engineer
The Qt Company
Erich-Thilo-Str. 10 12489
Berlin, Germany
www.qt.io
Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht Charlottenburg,
HRB 144331 B
More information about the Development
mailing list