{"id":106017,"date":"2021-12-09T07:00:00","date_gmt":"2021-12-09T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106017"},"modified":"2021-12-09T07:34:00","modified_gmt":"2021-12-09T15:34:00","slug":"20211209-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211209-00\/?p=106017","title":{"rendered":"If you&#8217;re going to configure a header file, you have to do it before you include the header file"},"content":{"rendered":"<p>In Windows, if you want the <code>windows.h<\/code> header file to default to the Unicode character set, you need to define the <code>UNICODE<\/code> symbol:<\/p>\n<pre>#define <a title=\"TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040212-00\/?p=40643\">UNICODE<\/a>\r\n#include &lt;windows.h&gt;\r\n<\/pre>\n<p>There&#8217;s no point defining the symbol after the horse has left the barn:<\/p>\n<pre>\/\/ Code in italics is wrong\r\n<i>#include &lt;windows.h&gt;\r\n#define UNICODE<\/i>\r\n<\/pre>\n<p><b>Related<\/b>: <a title=\"Don't forget to #define UNICODE if you want Unicode\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040715-00\/?p=38433\"> Don&#8217;t forget to #define UNICODE if you want Unicode<\/a>.<\/p>\n<p>Now, sure, a mistake like that is pretty obvious and easy to spot.<\/p>\n<p>But other mistakes might not be so easy to find.<\/p>\n<pre>#include &lt;stdio.h&gt;\r\n#include &lt;contoso.h&gt;\r\n#include &lt;fastmalloc.h&gt;\r\n#define UNICODE\r\n#include &lt;windows.h&gt;\r\n\r\nextern HWND g_mainWindow;\r\n\r\nvoid UpdateTitle(PCWSTR title)\r\n{\r\n  SetWindowText(g_mainWindow, title);\r\n}\r\n<\/pre>\n<p>This looks perfectly fine: We defined the <code>UNICODE<\/code> symbol before we included <code>windows.h<\/code>, but we still get compiler errors that suggest that the symbol didn&#8217;t take effect:<\/p>\n<pre style=\"white-space: pre-wrap;\">error C2664: 'BOOL SetWindowTextA(HWND,const char *)': cannot convert argument 2 from 'const wchar_t *' to 'const char *'\r\nnote: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast\r\n<\/pre>\n<p>The error message tells us that the compiler thinks that <code>Set\u00adWindow\u00adText<\/code> redirects to <code>Set\u00adWindow\u00adTextA<\/code>, and that function expects an ANSI string, not a Unicode one. But how can that be? We did the right thing and defined <code>UNICODE<\/code> symbol immediately before including <code>windows.h<\/code>.<\/p>\n<p>Yes, you defined it immediately before you included <code>windows.h<\/code>. But your inclusion of <code>windows.h<\/code> isn&#8217;t the one that counted.<\/p>\n<p>Somewhere in the chain of <code>#include<\/code> files that came before you included <code>windows.h<\/code> is somebody that did their own <code>#include &lt;windows.h&gt;<\/code>. That first inclusion did not have the <code>UNICODE<\/code> symbol defined, so the result was that all of the Windows macros redirected to the ANSI versions. You reconfigured the <code>windows.h<\/code> header afterward, but by then it was too late.<\/p>\n<p>You&#8217;ll need to move the definition to somewhere that occurs before the point at which the <code>windows.h<\/code> header is included for the first time. The safest place is to do it before including <i>anything<\/i>.<\/p>\n<pre><span style=\"color: blue;\">#define UNICODE<\/span>\r\n#include &lt;stdio.h&gt;\r\n#include &lt;contoso.h&gt;\r\n#include &lt;fastmalloc.h&gt;\r\n#include &lt;windows.h&gt;\r\n<\/pre>\n<p><b>Bonus chatter<\/b>: If you want to find out who is doing the early inclusion of <code>windows.h<\/code>, you can pass the <code>\/showIncludes<\/code> command line option to the Microsoft Visual C++ compiler. This can be configured in Visual Studio under <i>Project<\/i> \u2192 <i>Configuration Properties<\/i> \u2192 <i>C\/C++<\/i> \u2192 <i>Advanced<\/i> \u2192 <i>Show Includes<\/i> = <i>Yes (\/showIncludes)<\/i>. This will generate a hierarchy tree of every included file, and you can search it to see who included <code>windows.h<\/code>.<\/p>\n<p>For gcc, you don&#8217;t even need to do that much. You can reuse a trick we saw a little while ago: <a title=\"Compiler error message metaprogramming: Helping to find the conflicting macro definition\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211206-00\/?p=106002\"> Give a macro a conflicting definition and wait for the fireworks<\/a>.<\/p>\n<pre><span style=\"color: blue;\">#define CreateFile who_includes_windows_h_first<\/span>\r\n#define UNICODE\r\n#include &lt;stdio.h&gt;\r\n#include &lt;contoso.h&gt;\r\n#include &lt;fastmalloc.h&gt;\r\n#include &lt;windows.h&gt;\r\n<\/pre>\n<p>You will then get told<\/p>\n<pre>in file included from \/sdk\/fileapifromapp.h:19:\r\n                 from \/sdk\/winbase.h:42:\r\n                 from \/sdk\/windows.h:171:\r\n                 from \/contoso\/inc\/internal\/config.h:84:\r\n                 from \/contoso\/inc\/contoso.h:20:\r\n\/sdk\/fileapi.h:84: warning: \"CreateFile\" redefined\r\n<\/pre>\n<p>Bingo, it&#8217;s <code>contoso.h<\/code>, via its helper include file <code>internal\/config.h<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It sounds obvious, but you can be faked out.<\/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-106017","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It sounds obvious, but you can be faked out.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106017","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=106017"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106017\/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=106017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}