Why does QueryPerformanceFrequency fail with error 998?

This happened to me a couple of weeks ago, and it was weird enough that I thought I should write an article about it.

OK, let's say you need to do some metrics on a piece of code. "OK", you say "all I have to do is haul out QueryPerformanceFrequency and QueryPerformanceCounter, strut my funky 64 bit stuff, and I'll have all the numbers I need" (yes, I really do talk like Huggy Bear, at least in my head, anyway). So then you hack up the code, hit the compile key, fire up your test harness, reach for your coffee cup and... Oh. Hang on. That's not supposed to happen....

Error 998 (ERROR_NOACCESS - Invalid access to memory location).

The reason for this is subtle, and took me an hour or so of rooting around to discover. Like a great many people, I have to interface with other stuff, and in order to do so I have to have my code byte-aligned : in my project settings, the compiler is not set to the default 8 byte packing alignment, but 1 byte. Before crowds of people warn me about the performance loss, yes, I do know about this, I just have to do it, OK ? Everybody out there who has to deal with microcontrollers is nodding their head right now, trust me.

The problem is that QueryPerformanceFrequency doesn't seem to cater for this alignment oddity, and it cannot cope with accessing a variable which isn't quadword aligned.

There are two solutions to this problem : either move your variable to a place where you can guarantee it's quadword aligned (I moved mine to the beginning of the class declaration), or use #pragma pack to force the relevant section of your code to a pack setting of 8.