{"id":111250,"date":"2025-06-05T07:00:00","date_gmt":"2025-06-05T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=111250"},"modified":"2025-06-05T08:13:25","modified_gmt":"2025-06-05T15:13:25","slug":"20250605-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20250605-00\/?p=111250","title":{"rendered":"Why do some Windows functions fail if I pass an unaligned Unicode string?"},"content":{"rendered":"<p>A customer found that if they passed Unicode strings (which in Windows means strings encoded as UTF-16LE using the two-byte data type <code>wchar_t<\/code> as code units) which are not on even addresses, then some\u2014but not all\u2014functions fail to accept those strings. Why isn&#8217;t this documented?<\/p>\n<p>This is one of 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\"> ground rules for programming<\/a>: Pointers must be properly aligned unless explicitly permitted otherwise.<\/p>\n<p>In the C and C++ languages, forming an unaligned pointer is explicitly specified to return no useful value.<\/p>\n<p>In C:<\/p>\n<blockquote class=\"q\"><p>(6.3.2.3 Pointers) If the resulting pointer is not correctly aligned for the referenced type, <span style=\"border: solid 1px currentcolor;\">the behavior is undefined<\/span>.<\/p><\/blockquote>\n<p>In C++:<\/p>\n<blockquote class=\"q\"><p>[expr.static.cast](13) If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then <span style=\"border: solid 1px currentcolor;\">the resulting pointer value is unspecified<\/span>.<\/p><\/blockquote>\n<p>Therefore, simply creating a misaligned pointer already takes you outside the world of allowable (in C) or at least meaningful (in C++) operations, so you shouldn&#8217;t be surprised that using misaligned pointers results in nonsense.<\/p>\n<p>As for why certain functions get more upset than others, it&#8217;s all a matter how how those functions use the pointers and who detects the misaligned pointer.<\/p>\n<p>If you are using a processor that is alignment-sensitive, you will probably get a failure when the code tries to read the data from that pointer. If the access is made in user mode, you will get an access violation exception, and the process will probably crash. If the access is made in kernel mode, the kernel mode parameter validator will probably return an invalid parameter error. (Kernel mode must protect itself from user mode.)<\/p>\n<p>If you are using a processor that forgives misaligned data accesses, then you may get away with it for a while, until the code does something with the data that requires alignment. For example, atomic operations typically require aligned data, even on processors that are normally forgiving of misalignment.<\/p>\n<p>And even though x86-64 is generally alignment-forgiving, there are still places where it is alignment sensitive. For example, some instructions involving SIMD registers require alignment. SIMD registers are often used for copying blocks of memory around, and since <code>wchar_t<\/code> has 2-byte alignment, the <code>switch<\/code> statement for performing block copies has only 8 legal starting points out of 16, since all the odd addresses are invalid. If you pass an odd address, you might well fall through the <code>switch<\/code> statement and perform garbage copies.<\/p>\n<p>The Microsoft C++ compiler has a special nonstandard keyword <code>__unaligned<\/code> for declaring that a pointer may be unaligned, and this tells the compiler that any accesses to the data behind that pointer must use instructions that are alignment-forgiving. For some processors, <a title=\"Anybody who writes #pragma pack(1) may as well just wear a sign on their forehead that says &quot;I hate RISC&quot;\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200103-00\/?p=103290\"> this can be quite expensive<\/a>.<\/p>\n<p>Limit your use of misaligned pointers to places where misaligned pointers are expressly permitted. You can tell where those places are by looking for the Windows SDK macro <code>UNALIGNED<\/code>. For example:<\/p>\n<pre>LWSTDAPI_(int)\r\n    SHFormatDateTimeA(\r\n        _In_ const FILETIME <span style=\"border: solid 1px currentcolor;\">UNALIGNED<\/span> * pft,\r\n        _Inout_opt_ DWORD * pdwFlags,\r\n        _Out_writes_(cchBuf) LPSTR pszBuf,\r\n        UINT cchBuf); \r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Well, if you don&#8217;t align it, then you&#8217;ve already broken 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-111250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Well, if you don&#8217;t align it, then you&#8217;ve already broken the rules.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111250","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=111250"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/111250\/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=111250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=111250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=111250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}