{"id":96956,"date":"2017-09-07T07:00:00","date_gmt":"2017-09-07T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96956"},"modified":"2024-08-02T17:29:43","modified_gmt":"2024-08-03T00:29:43","slug":"20170907-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170907-00\/?p=96956","title":{"rendered":"What are anonymous structs, and more importantly, how do I tell windows.h to stop using them?"},"content":{"rendered":"<p>Windows header files take advantage of a language extension known as &#8220;anonymous structs&#8221; or &#8220;nameless structs&#8221;. It looks <a href=\"https:\/\/msdn.microsoft.com\/library\/windows\/desktop\/dd183565(v=vs.85).aspx\"> like this<\/a>:<\/p>\n<pre>typedef struct _devicemode {\r\n  TCHAR dmDeviceName[CCHDEVICENAME];\r\n  WORD dmSpecVersion;\r\n  WORD dmDriverVersion;\r\n  WORD dmSize;\r\n  WORD dmDriverExtra;\r\n  DWORD dmFields;\r\n  union {\r\n    struct {\r\n      short dmOrientation;\r\n      short dmPaperSize;\r\n      short dmPaperLength;\r\n      short dmPaperWidth;\r\n      short dmScale;\r\n      short dmCopies;\r\n      short dmDefaultSource;\r\n      short dmPrintQuality;\r\n    }; \/\/ <span style=\"border: solid 1px currentcolor;\">&lt;--- mystery #1<\/span>\r\n    struct {\r\n      POINTL dmPosition;\r\n      DWORD dmDisplayOrientation;\r\n      DWORD dmDisplayFixedOutput;\r\n    }; \/\/ <span style=\"border: solid 1px currentcolor;\">&lt;--- mystery #2<\/span>\r\n  }; \/\/ <span style=\"border: solid 1px currentcolor;\">&lt;--- mystery #3<\/span>\r\n  short dmColor;\r\n  short dmDuplex;\r\n  short dmYResolution;\r\n  short dmTTOption;\r\n  short dmCollate;\r\n  TCHAR dmFormName[CCHFORMNAME];\r\n  WORD dmLogPixels;\r\n  DWORD dmBitsPerPel;\r\n  DWORD dmPelsWidth;\r\n  DWORD dmPelsHeight;\r\n  union {\r\n    DWORD dmDisplayFlags;\r\n    DWORD dmNup;\r\n  }; \/\/ <span style=\"border: solid 1px currentcolor;\">&lt;--- mystery #4<\/span>\r\n  DWORD dmDisplayFrequency;\r\n#if(WINVER &gt;= 0x0400) \r\n  DWORD dmICMMethod;\r\n  DWORD dmICMIntent;\r\n  DWORD dmMediaType;\r\n  DWORD dmDitherType;\r\n  DWORD dmReserved1;\r\n  DWORD dmReserved2;\r\n#if (WINVER &gt;= 0x0500) || (_WIN32_WINNT &gt;= 0x0400)\r\n  DWORD dmPanningWidth;\r\n  DWORD dmPanningHeight;\r\n#endif\r\n#endif\r\n} DEVMODE, *PDEVMODE, *LPDEVMODE;\r\n<\/pre>\n<p>Members of structures and unions normally have names. But in the <code>DEVMODE<\/code> structure, there are some members with no name. There&#8217;s a union of two structures, and there&#8217;s no name for the union (mystery #3); furthermore, the two structures that are members of the union also have no names (mysteries #1 and #2). And there&#8217;s another union (mystery #4) that has no name.<\/p>\n<p>Let&#8217;s start with a smaller example. Consider this structure:<\/p>\n<pre>struct simple\r\n{\r\n int a;\r\n union {\r\n  int b;\r\n  int c;\r\n } d;\r\n} x;\r\n<\/pre>\n<p>In this example, we have a structure called <code>simple<\/code> and an instance of that structure in a variable called <code>x<\/code>. It consists of the following:<\/p>\n<ul>\n<li>An integer <code>a<\/code>, called <code>x.a<\/code>.<\/li>\n<li>An integer <code>b<\/code>, called <code>x.d.b<\/code>, which shares storage with<\/li>\n<li>An integer <code>c<\/code>, called <code>x.d.c<\/code>.<\/li>\n<\/ul>\n<p>A <i>nameless union<\/i> omits the name <code>d<\/code>.<\/p>\n<pre>struct simple2\r\n{\r\n int a;\r\n union {\r\n  int b;\r\n  int c;\r\n }; \/\/ <span style=\"border: solid 1px currentcolor;\">&lt;-- no name!<\/span>\r\n} x2;\r\n<\/pre>\n<p>This time, the contents are<\/p>\n<ul>\n<li>An integer <code>a<\/code>, called <code>x2.a<\/code>.<\/li>\n<li>An integer <code>b<\/code>, called <code>x2.b<\/code>, which shares storage with<\/li>\n<li>An integer <code>c<\/code>, called <code>x2.c<\/code>.<\/li>\n<\/ul>\n<p>See what happened there? Omitting the name on the union means that the members of the union are accessible without having to say the name of the union (which is a good thing, because that union has no name).<\/p>\n<p>Nameless unions are available in C and C++,\u00b9 and that&#8217;s what is happening in the <code>DEVMODE<\/code> structure. That solves mysteries #3 and #4.<\/p>\n<p>These extensions are supported by both the Visual Studio compiler as well as <a href=\"http:\/\/gcc.gnu.org\/onlinedocs\/gcc\/Unnamed-Fields.html\"> the GCC compiler<\/a>. But what if your compiler doesn&#8217;t?<\/p>\n<p>The answer lies in the actual definition in the header file.<\/p>\n<pre>typedef struct _devicemodeW { \r\n  WCHAR   dmDeviceName[CCHDEVICENAME]; \r\n  WORD   dmSpecVersion; \r\n  WORD   dmDriverVersion; \r\n  WORD   dmSize; \r\n  WORD   dmDriverExtra; \r\n  DWORD  dmFields; \r\n  union {\r\n    struct {\r\n      short dmOrientation;\r\n      short dmPaperSize;\r\n      short dmPaperLength;\r\n      short dmPaperWidth;\r\n      short dmScale; \r\n      short dmCopies; \r\n      short dmDefaultSource; \r\n      short dmPrintQuality; \r\n    } <span style=\"border: solid 1px currentcolor;\">DUMMYSTRUCTNAME<\/span>; \/\/ magic #1\r\n    struct {\r\n      POINTL dmPosition;\r\n      DWORD  dmDisplayOrientation;\r\n      DWORD  dmDisplayFixedOutput;\r\n    } <span style=\"border: solid 1px currentcolor;\">DUMMYSTRUCTNAME2<\/span>; \/\/ magic #2\r\n  } <span style=\"border: solid 1px currentcolor;\">DUMMYUNIONNAME<\/span>; \/\/ magic #3\r\n  short  dmColor; \r\n  short  dmDuplex; \r\n  short  dmYResolution; \r\n  short  dmTTOption; \r\n  short  dmCollate; \r\n  WCHAR  dmFormName[CCHFORMNAME]; \r\n  WORD   dmLogPixels; \r\n  DWORD  dmBitsPerPel; \r\n  DWORD  dmPelsWidth; \r\n  DWORD  dmPelsHeight; \r\n  union {\r\n    DWORD  dmDisplayFlags; \r\n    DWORD  dmNup;\r\n  } <span style=\"border: solid 1px currentcolor;\">DUMMYUNIONNAME2<\/span>; \/\/ magic #4\r\n  DWORD  dmDisplayFrequency; \r\n#if(WINVER &gt;= 0x0400) \r\n  DWORD  dmICMMethod;\r\n  DWORD  dmICMIntent;\r\n  DWORD  dmMediaType;\r\n  DWORD  dmDitherType;\r\n  DWORD  dmReserved1;\r\n  DWORD  dmReserved2;\r\n#if (WINVER &gt;= 0x0500) || (_WIN32_WINNT &gt;= 0x0400)\r\n  DWORD  dmPanningWidth;\r\n  DWORD  dmPanningHeight;\r\n#endif\r\n#endif\r\n} DEVMODEW,*LPDEVMODEW,*PDEVMODEW;\r\n<\/pre>\n<p>There are magic symbols called <code>DUMMY<\/code><code>SOMETHING<\/code><code>NAME<\/code> where a name would normally go.<\/p>\n<p>How curious.<\/p>\n<p>If you then search the Windows header files for definitions of these magic symbols, you find them here in <code>winnt.h<\/code>:<\/p>\n<pre>\/\/\r\n\/\/ For compilers that don't support nameless unions\/structs\r\n\/\/\r\n#ifndef DUMMYUNIONNAME\r\n#if defined(NONAMELESSUNION) || !defined(_MSC_EXTENSIONS)\r\n#define DUMMYUNIONNAME   u\r\n#define DUMMYUNIONNAME2  u2\r\n#define DUMMYUNIONNAME3  u3\r\n#define DUMMYUNIONNAME4  u4\r\n#define DUMMYUNIONNAME5  u5\r\n#define DUMMYUNIONNAME6  u6\r\n#define DUMMYUNIONNAME7  u7\r\n#define DUMMYUNIONNAME8  u8\r\n#define DUMMYUNIONNAME9  u9\r\n#else\r\n#define DUMMYUNIONNAME\r\n#define DUMMYUNIONNAME2\r\n#define DUMMYUNIONNAME3\r\n#define DUMMYUNIONNAME4\r\n#define DUMMYUNIONNAME5\r\n#define DUMMYUNIONNAME6\r\n#define DUMMYUNIONNAME7\r\n#define DUMMYUNIONNAME8\r\n#define DUMMYUNIONNAME9\r\n#endif\r\n#endif \/\/ DUMMYUNIONNAME\r\n\r\n#ifndef DUMMYSTRUCTNAME\r\n#if defined(NONAMELESSUNION) || !defined(_MSC_EXTENSIONS)\r\n#define DUMMYSTRUCTNAME  s\r\n#define DUMMYSTRUCTNAME2 s2\r\n#define DUMMYSTRUCTNAME3 s3\r\n#define DUMMYSTRUCTNAME4 s4\r\n#define DUMMYSTRUCTNAME5 s5\r\n#else\r\n#define DUMMYSTRUCTNAME\r\n#define DUMMYSTRUCTNAME2\r\n#define DUMMYSTRUCTNAME3\r\n#define DUMMYSTRUCTNAME4\r\n#define DUMMYSTRUCTNAME5\r\n#endif\r\n#endif \/\/ DUMMYSTRUCTNAME\r\n<\/pre>\n<p>Ah, now the pieces all fall into place.<\/p>\n<p>If you define the symbol <code>NO<\/code><code>NAMELESS<\/code><code>UNION<\/code>, then the symbols <code>DUMMY<\/code><code>SOMETHING<\/code><code>NAME<\/code> are defined to expand to actual names. For dummy unions, they are <code>u<\/code>, <code>u2<\/code>, <code>u3<\/code>, and so on. For dummy structures, they follow the same pattern, but with <code>s<\/code> instead of <code>u<\/code>.<\/p>\n<p>This means that if you indicate that you don&#8217;t want the header files to use nameless unions, the nameless structures and unions magically get names! The names are not particularly exciting, but at least they have names.<\/p>\n<pre>DEVICEMODE dm;\r\ndm.dmPosition = ...;      \/\/ if nameless unions are enabled\r\ndm.u.s2.dmPosition = ...; \/\/ if nameless unions are disabled\r\n<\/pre>\n<p>Notice that I didn&#8217;t use any Microsoft insider information to solve this mystery. All the information you need is right there, if you just follow the symbol definitions.<\/p>\n<p>\u00b9 The history here is unclear. Wikipedia claims that <a href=\"https:\/\/en.wikipedia.org\/wiki\/Union_type#Anonymous_union\"> anonymous unions are in C++ and C11<\/a>, but Stack Overflow claims that <a href=\"http:\/\/stackoverflow.com\/a\/12785369\/902497\"> C++ supports anonymous unions only because C did<\/a>. So there&#8217;s some sort of circular causality loop here.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The struct with no name.<\/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-96956","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The struct with no name.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96956","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=96956"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96956\/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=96956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}