{"id":112110,"date":"2026-03-04T07:00:00","date_gmt":"2026-03-04T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112110"},"modified":"2026-03-04T10:23:22","modified_gmt":"2026-03-04T18:23:22","slug":"20260304-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20260304-00\/?p=112110","title":{"rendered":"Aha, I found a counterexample to the documentation that says that <CODE>Query&shy;Performance&shy;Counter<\/CODE> never fails"},"content":{"rendered":"<p>In the documentation that describes the high-resolution timestamps, there is a question-and-answer section.<\/p>\n<blockquote class=\"q\">\n<p><b>Under what circumstances does QueryPerformanceFrequency return FALSE, or QueryPerformanceCounter return zero?<\/b><\/p>\n<p>This won&#8217;t occur on any system that runs Windows XP or later.<\/p>\n<\/blockquote>\n<p>People on Stack Overflow have noted, &#8220;Nuh-uh! <a href=\"https:\/\/stackoverflow.com\/a\/27258700\/902497\"> I can get it to fail even on Windows XP and later<\/a>!&#8221;<\/p>\n<blockquote class=\"q\"><p>The function can fail with error code <code>ERROR_NOACCESS<\/code> (Invalid access to memory location) if the variable is not <i>double-word<\/i> (8-byte) aligned.<\/p><\/blockquote>\n<p>So who&#8217;s right?<\/p>\n<p>The documentation assumes that you are passing valid parameters. Specifically, the pointer parameter is a valid pointer to a writable <code>LARGE_INTEGER<\/code> structure. And that means that it&#8217;s not a null pointer, it&#8217;s not a pointer to unallocated memory, it&#8217;s not a pointer to read-only memory, it&#8217;s not a pointer to memory that is freed while the function is executing, you don&#8217;t write to the memory while <code>Query\u00adPerformance\u00adCounter<\/code> is running, and it&#8217;s a pointer to properly aligned <code>LARGE_INTEGER<\/code> 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.)<\/p>\n<p>The <code>LARGE_INTEGER<\/code> structure as <code>LONGLONG<\/code> alignment, which on Windows means 8-byte alignment, because <a title=\"What structure packing do the Windows SDK header files expect?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20090422-00\/?p=18493\"> the default structure packing is <tt>\/Zp8<\/tt><\/a>. Therefore, your output <code>LARGE_INTEGER<\/code> was not valid. (Indeed, in the example given, it&#8217;s not even a <code>LARGE_INTEGER<\/code>!)<\/p>\n<p>If you pass invalid parameters, then you have broken the <a title=\"Basic ground rules for programming - function parameters and how they are used\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060320-13\/?p=31853\"> basic ground rules for programming<\/a>, 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&#8217;t cross a security boundary).<\/p>\n<p>The way they got it to fail was by passing invalid parameters. Clearly the function can&#8217;t succeed if you don&#8217;t give a valid place to put the answer.<\/p>\n<p>But just to forestall the &#8220;Nuh uh&#8221;-ers, I made an update to the documentation for <code>Query\u00adPerformance\u00adCounter<\/code>:<\/p>\n<blockquote class=\"q\"><p>On systems that run Windows XP or later, the function will always succeed <span style=\"border: solid 1px currentcolor;\">when given valid parameters<\/span> and will thus never return zero.<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Of course, anything can happen if you break the rules.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-112110","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Of course, anything can happen if you break the rules.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=112110"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112110\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=112110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}