From e80faf3db61ca9c701cd86876e3bce8e33226576 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 17 Oct 2016 13:00:04 +0200 Subject: QTimer: don't circumvent safety net By templating on the types and unconditionally using duration_cast to coerce the duration into a milliseconds, we violate a principal design rule of , namely that non- narrowing conversions are implicit, but narrowing conversions need duration_cast. By accepting any duration, we allow non- sensical code such as QTimer::singleShot(10us, ...) to compile, which is misleading, since it's actually a zero- timeout timer. Overloading a non-template with a template also has adverse effects: it breaks qOverload(). Fix by replacing the function templates with functions that just take std::chrono::milliseconds. This way, benign code such as QTimer::singleShot(10s, ...) QTimer::singleShot(10min, ...) QTimer::singleShot(1h, ...) work as expected, but attempts to use sub-millisecond resolution fails to compile / needs an explicit user- provided duration_cast. To allow future extension to more precise timers, forcibly inline the functions, so they don't partake in the ABI of the class and we can later support sub-millisecond resolution by simply taking micro- or nano- instead of milliseconds. Change-Id: I12c9a98bdabefcd8ec18a9eb09f87ad908d889de Reviewed-by: Thiago Macieira --- src/corelib/kernel/qtimer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/corelib/kernel/qtimer.cpp') diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 6d39233aa7..4a5738a6dc 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -533,7 +533,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! - \fn void QTimer::singleShot(std::chrono::duration value, const QObject *receiver, const char *member) + \fn void QTimer::singleShot(std::chrono::milliseconds msec, const QObject *receiver, const char *member) \since 5.8 \overload \reentrant @@ -545,13 +545,13 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv create a local QTimer object. The \a receiver is the receiving object and the \a member is the slot. The - time interval is given in the duration object \a value. + time interval is given in the duration object \a msec. \sa start() */ /*! - \fn void QTimer::singleShot(std::chrono::duration value, Qt::TimerType timerType, const QObject *receiver, const char *member) + \fn void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, const QObject *receiver, const char *member) \since 5.8 \overload \reentrant @@ -563,18 +563,18 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv create a local QTimer object. The \a receiver is the receiving object and the \a member is the slot. The - time interval is given in the duration object \a value. The \a timerType affects the + time interval is given in the duration object \a msec. The \a timerType affects the accuracy of the timer. \sa start() */ /*! - \fn void QTimer::start(std::chrono::duration value) + \fn void QTimer::start(std::chrono::milliseconds msec) \since 5.8 \overload - Starts or restarts the timer with a timeout of duration \a value. + Starts or restarts the timer with a timeout of duration \a msec milliseconds. If the timer is already running, it will be \l{QTimer::stop()}{stopped} and restarted. -- cgit v1.2.3