What happens when GetTickCount() wraps?

From the docs:

The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days. To avoid this problem, use GetTickCount64. Otherwise, check for an overflow condition when comparing times.

However, DWORD is unsigned - so you should be okay. 0 - "very big number" = "small number" (assuming you don't have any overflow checking active, of course). I had a previous edit which suggested you'd get a negative number, but that was before I took into account that DWORD is unsigned.

You'll still have a problem if the operation takes just under 49.7 days though. That may not be an issue for you ;)

One way to test would be to stub out the GetTickCount() method so you could write unit tests where you explicitly make it wrap. Then again, if you're really only doubting the arithmetic part, you can easily write unit tests for that :) Really, the fact that the number is coming from a system clock is pretty much irrelevant so long as you know the behaviour when it wraps - and that's specified in the documentation.


Nothing bad happens, as long as:

  • You subtract DWORDs, rather than converting to some other type first.

  • Nothing you're trying to time takes longer than 49.7 days.

This is because unsigned arithmetic overflow is well-defined in C, and wrapping behavior does exactly what we want.

DWORD t1, t2;
DWORD difference;

t1 = GetTickCount();
DoSomethingTimeConsuming();
t2 = GetTickCount();

t2 - t1 will produce the correct the value, even if GetTickCount wraps around. Just don't convert t2 and t1 to some other type (e.g. int or double) before doing the subtraction.

This won't work if the programming language treats overflow as an error. It also won't work if DoSomethingTimeConsuming() takes longer than 49.7 days. You can't tell just by looking at t2 and t1 how many times GetTickCount wrapped around, unfortunately.


Let's start with the the usual case, where no wraparound comes into play:

t1 = 13487231
t2 = 13492843

Here, t2 - t1 = 5612, which means the operation took about five seconds.

Now consider an operation that takes a short amount of time, but where GetTickCount did wrap around:

t1 = 4294967173
t2 = 1111

The operation took 1234ms, but the timer wrapped around, and 1111 - 4294967173 is the bogus value of -4294966062. What ever will we do?

Well, modulo 232, the result of subtraction wraps around, too:

(DWORD)-4294966062 == (DWORD)1234

Finally, consider the edge case where an operation takes nearly 232 milliseconds, but not quite:

t1 = 2339189280
t2 = 2339167207

Here, GetTickCount wrapped around, and came right back around where it was.

Now t2 - t1 yields the bogus-looking value of 4294945223. That's because that's the amount of time the operation actually took!

In general:

(base + offset) - base ≡ offset mod 2^32

If you want to test what happens when GetTickCount() wraps, you could enable Application Verifier's TimeRollOver test.

From Using Application Verifier Within Your Software Development Lifecycle:

TimeRollOver forces the GetTickCount and TimeGetTime APIs to roll over faster than they normally would. This allows applications to test their handling of time rollover more easily.