{"id":106002,"date":"2021-12-06T07:00:00","date_gmt":"2021-12-06T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106002"},"modified":"2021-12-06T06:41:16","modified_gmt":"2021-12-06T14:41:16","slug":"20211206-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211206-00\/?p=106002","title":{"rendered":"Compiler error message metaprogramming: Helping to find the conflicting macro definition"},"content":{"rendered":"<p>Say you want to require that a preprocessor macro is set a particular way:<\/p>\n<pre>#include &lt;contoso.h&gt;\r\n#if CONTOSO_VERSION != 314\r\n#error This header file requires version 314.\r\n#endif\r\n<\/pre>\n<p>Okay, if the version isn&#8217;t set correctly, you will indeed get the error, but that doesn&#8217;t help the user much with figuring out why the version number is incorrect.<\/p>\n<p>You might try this:<\/p>\n<pre>#include &lt;contoso.h&gt;\r\n#if CONTOSO_VERSION != 314\r\n#error This header file requires version 314 \\\r\n(got CONTOSO_VERSION instead)\r\n#endif\r\n<\/pre>\n<p>Unfortunately, it doesn&#8217;t work:<\/p>\n<pre style=\"white-space: pre-wrap;\">\/\/ MSVC\r\nfatal error C1189: #error:  This header file requires version 314 (got CONTOSO_VERSION instead)\r\n\r\n\/\/ gcc\r\nerror: #error This header file requires version 314 (got CONTOSO_VERSION instead)\r\n\r\n\/\/ clang\r\nerror: This header file requires version 314 (got CONTOSO_VERSION instead)\r\n\r\n\/\/ icc\r\nerror: #error directive: This header file requires version 314 (got CONTOSO_VERSION instead)\r\n<\/pre>\n<p>None of them substitute the macro in the error message, so you don&#8217;t see what version you actually got.<\/p>\n<p>Here&#8217;s the trick: Just redefine the symbol.<\/p>\n<pre>#include &lt;contoso.h&gt;\r\nstatic_assert(CONTOSO_VERSION == 314,\r\n             \"This header file requires version 314.\");\r\n#define CONTOSO_VERSION 314\r\n<\/pre>\n<pre style=\"white-space: pre-wrap;\">\/\/ MSVC\r\nerror C2338: This header file requires version 314.\r\nwarning C4005: 'CONTOSO_VERSION': macro redefinition\r\nC:\\contoso\\v271\\contoso.h(5): note: see  previous definition of 'CONTOSO_VERSION'\r\n\r\n\/\/ gcc\r\nwarning: \"CONTOSO_VERSION\" redefined\r\n  3 | #define CONTOSO_VERSION 314\r\n\r\nin file included from widget.h:1:\r\n\/contoso\/v271\/contoso.h:5: note: this is the location of the previous definition\r\n  5 | #define CONTOSO_VERSION 271\r\n\r\nerror: static assertion failed: This header file requires version 314.\r\n  2 | static_assert(CONTOSO_VERSION == 314,\r\n\r\n\/\/ clang\r\nwarning: 'CONTOSO_VERSION' macro redefined [Wmacro-redefined]\r\n#define CONTOSO_VERSION 314\r\n\r\n\/contoso\/v271\/contoso.h:5:9: note: previous definition is here\r\n#define CONTOSO_VERSION 271\r\n\r\nerror: static_assert failed due to requirement '271 == 314' \"This header file requires version 314.\"\r\nstatic_assert(CONTOSO_VERSION == 314,\r\n\r\n\/\/ icc\r\nerror: static assertion failed with \"This header file requires version 314.\"\r\nstatic_assert(CONTOSO_VERSION == 314,\r\n\r\nwarning #47: incompatible redefinition of macro \"CONTOSO_VERSION\" (declared at line 5 of \"\/contoso\/v271\/contoso.h\")\r\n#define CONTOSO_VERSION 314\r\n<\/pre>\n<p>All of the major compilers provide the courtesy of telling you where the previous conflicting definition was made. From the error message, it is evident that we are including the <code>contoso.h<\/code> header file from the <code>v271<\/code> directory, when we presumably meant to include from the <code>v314<\/code> directory. The thing to investigate, therefore, is the project configuration where the include directories are specified, and fix it so that the correct version of <code>contoso.h<\/code> gets included.<\/p>\n<p>This trick takes advantage of the fact that the C and C++ languages both permit a macro symbol to be defined twice, provided that the second definition is identical to the first. If not, then the program is <i>ill-formed<\/i> and requires a diagnostic.<\/p>\n<p>So we just redefine the macro to the value we want. If it has that value, then everything is great. If not, then a diagnostic is required. And all of the major compilers point you at the previous definition, which will help you figure out why there is a conflict.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Shaping the code so a required diagnostic will be useful.<\/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-106002","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Shaping the code so a required diagnostic will be useful.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106002","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=106002"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106002\/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=106002"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106002"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106002"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}