In the documentation that describes the high-resolution timestamps, there is a question-and-answer section.
Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?
This won’t occur on any system that runs Windows XP or later.
People on Stack Overflow have noted, “Nuh-uh! I can get it to fail even on Windows XP and later!”
The function can fail with error code
ERROR_NOACCESS(Invalid access to memory location) if the variable is not double-word (8-byte) aligned.
So who’s right?
The documentation assumes that you are passing valid parameters. Specifically, the pointer parameter is a valid pointer to a writable LARGE_INTEGER structure. And that means that it’s not a null pointer, it’s not a pointer to unallocated memory, it’s not a pointer to read-only memory, it’s not a pointer to memory that is freed while the function is executing, you don’t write to the memory while QueryÂPerformanceÂCounter is running, and it’s a pointer to properly aligned LARGE_INTEGER structure. (There are probably other ways the parameter can be invalid; those are just the ones I could think of off the top of my head.)
The LARGE_INTEGER structure as LONGLONG alignment, which on Windows means 8-byte alignment, because the default structure packing is /Zp8. Therefore, your output LARGE_INTEGER was not valid. (Indeed, in the example given, it’s not even a LARGE_INTEGER!)
If you pass invalid parameters, then you have broken the basic ground rules for programming, and the results will be unpredictable. The function might return failure, it might return success but produce garbage results, it might crash your process, it might merely corrupt your process in a way that causes it to crash 10 minutes later. Everything is on the table (as long as it doesn’t cross a security boundary).
The way they got it to fail was by passing invalid parameters. Clearly the function can’t succeed if you don’t give a valid place to put the answer.
But just to forestall the “Nuh uh”-ers, I made an update to the documentation for QueryÂPerformanceÂCounter:
On systems that run Windows XP or later, the function will always succeed when given valid parameters and will thus never return zero.
I believe the actual meaning of this sentence is that, starting from Windows XP, its underlying mechanisms are no longer optional features for the kernel, so when it is unavailable, the system cannot start, or the system itself is faulty.
That’s me. I knew it when i asked it. But you have to understand: i was trying to figure out why it was returning `false`.
So i consult the documentation:
> It can **never** return false
And then eventually i did figure it out; and wanted to help others in the same boat.
I thought that document was just wrong for other reasons. 32 bit Windows prior to Windows 10 would actually install and run on a computer lacking any higher resolution timer than 18.2 ticks per second. It’s clearly not the intended hardware, but it does run.
There are multiple options for QSC function, so you don’t need HPET.
See main docs on QSC: Acquiring high-resolution time stamps – Hardware timer info
What language are they even using? I’m not familiar w/ any which use `@` as a prefix operator to get a variable’s address? I was surprised the code example didn’t have a cast to `LARGE_INTEGER*`, as that cast would have been a clear sign of tomfoolery
Pascal and its descendants use @ as the “address-of” operator. Apparently some people still use Delphi and Free Pascal, so sometimes you might run into Pascal syntax.