{"id":110188,"date":"2024-08-28T07:00:00","date_gmt":"2024-08-28T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110188"},"modified":"2024-08-28T09:21:06","modified_gmt":"2024-08-28T16:21:06","slug":"20240828-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240828-00\/?p=110188","title":{"rendered":"On the strange status of <CODE>wchar_t<\/CODE> in classic MIDL"},"content":{"rendered":"<p>In Windows IDL files, there is a type called <code>wchar_t<\/code>. What does it represent?<\/p>\n<p>If you&#8217;re asking about the ABI representation of a <code>wchar_t<\/code>, then that&#8217;s easy: It represents a 16-bit integer value that holds a UTF-16 code unit.<\/p>\n<p>But if you&#8217;re asking about what data type is used to hold that 16-bit integer value, well, things get a little more complicated.<\/p>\n<p>With one exception, when you use the <code>wchar_t<\/code> type in a Windows IDL file, it is just passed through to the header file, and it is up to the code that includes the header file to decide what <code>wchar_t<\/code> means.<\/p>\n<ul>\n<li>If the including code is written in C, then for the Microsoft Visual C++ toolchain, the meaning of <code>wchar_t<\/code> comes from <code>wchar.h<\/code>, where it is defined as <code>unsigned short<\/code>.<\/li>\n<li>If the including code is written in C++, then for the Microsoft Visual C++ toolchain, the meaning of <code>wchar_t<\/code> depends on how you set the <code>\/Zc:wchar_t<\/code> compiler flag.\n<ul>\n<li>If you specify <code>\/Zc:wchar_t<\/code>, or don&#8217;t specify anything at all, then <code>wchar_t<\/code> represents a unique data type whose binary representation is a 16-bit integer. <a title=\"What is __wchar_t (with the leading double underscores) and why am I getting errors about it?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20161201-00\/?p=94836\"> We learned about this special data type some time ago<\/a>.<\/li>\n<li>If you specify <code>\/Zc:wchar_t-<\/code>, then <code>wchar_t<\/code> is not predefined, and the Windows header files define it to mean <code>unsigned short<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>But at least from the IDL compiler&#8217;s point of view, all this nonsense is irrelevant. The IDL compiler just emits <code>wchar_t<\/code> into the header file and leaves it to the C or C++ compiler to figure out what it means.<\/p>\n<p>There is however, one frustrating wrinkle to this seemingly simple plan.<\/p>\n<p>The Windows IDL compiler predates the standardization of <code>wchar_t<\/code>, and for historical reasons, it lets you provide your own definition of <code>wchar_t<\/code>.<\/p>\n<pre>typedef unsigned short wchar_t;\r\n<\/pre>\n<p>If you choose to define it manually, then the IDL compiler dutifully copies that definition into the generated header file.<\/p>\n<p>And now you&#8217;re at war with the C++ compiler, because your definition of <code>wchar_t<\/code> as <code>unsigned short<\/code> will conflict with the standard built-in definition of <code>wchar_t<\/code> as a unique type. In order to avoid this problem, you&#8217;ll have to use the <code>\/Zc:wchar_t-<\/code> option to tell the C++ compiler not to treat <code>wchar_t<\/code> as a unique type and allow it to be given a custom definition.<\/p>\n<p>This whole nonsense about letting you provide a custom definition for <code>wchar_t<\/code> exists only for backward compatibility, and you shouldn&#8217;t do it if you know what&#8217;s good for you. To avoid making things <i>too<\/i> crazy, the only allowable custom definition for <code>wchar_t<\/code> is as <code>unsigned short<\/code>. Any other definition is rejected.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From the era before <CODE>wchar_t<\/CODE> was a standard type.<\/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-110188","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>From the era before <CODE>wchar_t<\/CODE> was a standard type.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110188","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=110188"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110188\/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=110188"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110188"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110188"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}