Perfect timing

I'm sitting here at the airport in San Francisco after a very successful week of conferences and talking to people, with some time to kill before my flight leaves. I attended 2 days of Camp KDE and 3 days of the Linux Collaboration Summit, where I spent most of my time attending the MeeGo sessions and talking to other MeeGo collaborators. I also found the time to visit the hotel where the MeeGo Conference San Francisco 2011 will be held and it looks great.

All of this thinking of time available, time to kill, time spent has made me think of some weird, usually timing-sensitive errors that we developers find in programming. These errors usually happen once and never again, so you chalk it up to "spurious error" and never check again. There's one particular error that usually happens twice a year and I expected it to happen two weeks ago, but it didn't.

If a particular failure happens twice a year in thousands or even millions of runs in that period, you'd be excused if you attributed that to "the alignment of the planets" and simply went on your merry way. This particular case I'm thinking of is not due to the alignment of the planets, but to the daylight savings time change in Europe. That's why this particular error happens twice every year, yet we aren't likely to come and fix it.

I did fix another class of errors after I introduced QElapsedTimer. Unlike QTime, I added no constructor to this class so that it would be POD. This means that, during the conversion to QElapsedTimer, I had to track down several places where the elapsed time was being checked against an uninitialised or invalid timer.

This because, even if you invalidate() the QElapsedTimer object, the result is different. Internally, QTime stores the number of milliseconds since local midnight, but an invalidated or a default-constructed QTime contains the value -1. So if you get the elapsed time on a not-started QTime, you get the current time plus 1 millisecond, which is always positive. QElapsedTimer, however, has a different behaviour and checking the elapsed time against a not-started timer often results in is a very big negative number (it always does if you check against an invalidated timer).

In the process of porting, I found several places in the code with a decision with a condition like:

    elapsed() > certainAmount

If the timer isn't properly started before this check, the result of the check is very different. With QTime, the condition is almost always true, whereas with QElapsedTimer, it's almost certainly false.

Techincally speaking, those codepaths were already wrong, since they would fail in the first "certainAmount" of milliseconds in the day. QElapsedTimer showed the error. So every time we fix the mistake of failing to start the timer, we're fixing a bug that would show up in the first 250 or 400 milliseconds or so of the day.

If you encountered this error, you'd probably just say it was "the alignment of the planets", but now we know better. :-)