{"id":7941,"date":"2016-03-30T14:00:16","date_gmt":"2016-03-30T21:00:16","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/?p=7941"},"modified":"2019-02-18T18:04:48","modified_gmt":"2019-02-18T18:04:48","slug":"optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3\/","title":{"rendered":"Optimizing the Layout of Empty Base Classes in VS2015 Update 2"},"content":{"rendered":"<p>The C++ Standard has only a handful of requirements regarding how a class is laid out in memory, one of which is that the size of a most derived object shall have a non-zero size and shall occupy one or more bytes of storage.  Because this requirement only extends to most derived objects, base class subobjects are not subjected to that constraint.  Taking advantage of this liberty in the standard is commonly referred to as the Empty Base Class Optimization (EBCO), and results in reduced memory consumption, which can improve performance.  The Visual C++ compiler has historically had limited support for EBCO; however, in <a href=\"https:\/\/www.visualstudio.com\/news\/vs2015-update2-vs\" title=\"Visual Studio 2015 Update 2\">Visual Studio 2015 Update 2<\/a>, we have added a new <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> attribute for class types that takes full advantage of this optimization.<\/p>\n<p>In Visual Studio 2015, barring any <code style=\"font-size: 90%\">__declspec(align())<\/code> or <code style=\"font-size: 90%\">alignas()<\/code> specifications, an empty class is 1 byte in size:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Empty1 {};\r\nstatic_assert(sizeof(Empty1) == 1, \"Empty1 should be 1 byte\");<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A class with a single non-static data member of type <code style=\"font-size: 90%\">char<\/code> is also 1 byte in size:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Struct1\r\n{\r\n  char c;\r\n};\r\nstatic_assert(sizeof(Struct1) == 1, \"Struct1 should be 1 byte\");<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Combining these classes in a class hierarchy also results in a class that is 1 byte in size:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Derived1 : Empty1\r\n{\r\n  char c;\r\n};\r\nstatic_assert(sizeof(Derived1) == 1, \"Derived1 should be 1 byte\");<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This is the Empty Base Class Optimization at work, as without it <code style=\"font-size: 90%\">Derived1<\/code> would be 2 bytes in size, 1 byte for <code style=\"font-size: 90%\">Empty1<\/code> and 1 byte for <code style=\"font-size: 90%\">Derived1::c<\/code>.  The class layout is also optimal when there is a chain of empty classes:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Empty2 : Empty1 {};\r\nstruct Derived2 : Empty2\r\n{\r\n  char c;\r\n};\r\nstatic_assert(sizeof(Derived2) == 1, \"Derived2 should be 1 byte\");<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>However, the default class layout in Visual Studio 2015 does not take advantage of EBCO in multiple inheritance scenarios:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Empty3 {};\r\nstruct Derived3 : Empty2, Empty3\r\n{\r\n  char c;\r\n};\r\nstatic_assert(sizeof(Derived3) == 1, \"Derived3 should be 1 byte\"); \/\/ Error<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Although <code style=\"font-size: 90%\">Derived3<\/code> could be 1 byte in size, the default class layout results in it being 2 bytes in size.  The class layout algorithm is adding 1 byte of padding between any two consecutive empty base classes, effectively resulting in <code style=\"font-size: 90%\">Empty2<\/code> consuming an extra byte within <code style=\"font-size: 90%\">Derived3<\/code>:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived3  size(2):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n1  | +--- (base class Empty3)\r\n   | +---\r\n1  | c\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The effects of this suboptimal layout are compounded when the alignment requirements of a subsequent base class or member subobject necessitate additional padding:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Derived4 : Empty2, Empty3\r\n{\r\n  int i;\r\n};\r\nstatic_assert(sizeof(Derived4) == 4, \"Derived4 should be 4 bytes\"); \/\/ Error<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The natural alignment for an object of type <code style=\"font-size: 90%\">int<\/code> is 4 bytes, so an additional 3 bytes of padding need to be added after <code style=\"font-size: 90%\">Empty3<\/code> to correctly align <code style=\"font-size: 90%\">Derived4::i<\/code>:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived4 size(8):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n1  | +--- (base class Empty3)\r\n   | +---\r\n   | &lt;alignment member&gt; (size=3)\r\n4  | i\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Another issue with the default class layout in Visual Studio 2015 is that an empty base class may be laid out at an offset past the end of the class:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct Struct2 : Struct1, Empty1\r\n{\r\n};\r\nstatic_assert(sizeof(Struct2) == 1, \"Struct2 should be 1 byte\");<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Struct2 size(1):\r\n   +---\r\n0  | +--- (base class Struct1)\r\n0  | | c\r\n   | +---\r\n1  | +--- (base class Empty1)\r\n   | +---\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Although <code style=\"font-size: 90%\">Struct2<\/code> is the optimal size, <code style=\"font-size: 90%\">Empty1<\/code> is laid out at offset 1 within <code style=\"font-size: 90%\">Struct2<\/code> but the size of <code style=\"font-size: 90%\">Struct2<\/code> is not increased to account for it. As a result, for an array <code style=\"font-size: 90%\">A<\/code> of <code style=\"font-size: 90%\">Struct2<\/code> objects, the address of the <code style=\"font-size: 90%\">Empty1<\/code> subobject of <code style=\"font-size: 90%\">A[0]<\/code> will be the same as the address of <code style=\"font-size: 90%\">A[1]<\/code>, which should not be the case. This issue would not occur if <code style=\"font-size: 90%\">Empty1<\/code> were laid out at offset 0 within <code style=\"font-size: 90%\">Struct2<\/code>, thereby overlapping the <code style=\"font-size: 90%\">Struct1<\/code> subobject.\nIt would be great if the default layout algorithm could be modified to address these limitations and fully take advantage of EBCO; however, such a change can&#8217;t be made in an Update release of Visual Studio 2015.  One of the requirements of an Update release is that object files and libraries built with the initial release of Visual Studio 2015 continue to be compatible with those built with future Update releases.  If the default layout for a class were to change as a result of EBCO, every object file and library that contains the class definition would need to be re-compiled so they all agree on the class layout.  This would also extend to libraries obtained from external sources, which would require the developer of such libraries to provide independent versions that are compiled with and without the EBCO layout so they can support customers who aren&#8217;t compiling with the latest Update release.\nAlthough we can&#8217;t change the default layout, we can provide a means to change the layout on a per-class basis, and this is what we have done in Visual Studio 2015 Update 2 with the addition of the <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> class attribute.  A class defined with this attribute will make full use of EBCO.<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct __declspec(empty_bases) Derived3 : Empty2, Empty3\r\n{\r\n  char c;\r\n};\r\nstatic_assert(sizeof(Derived3) == 1, \"Derived3 should be 1 byte\"); \/\/ No Error<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived3  size(1):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n0  | +--- (base class Empty3)\r\n   | +---\r\n0  | c\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>All of <code style=\"font-size: 90%\">Derived3<\/code>&#8216;s subobjects are laid out at offset 0, and its size is the optimal 1 byte.  One important point to remember is that <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> only affects the layout of the class to which it is applied; it is not applied recursively to base classes:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct __declspec(empty_bases) Derived5 : Derived4\r\n{\r\n};\r\nstatic_assert(sizeof(Derived5) == 4, \"Derived5 should be 4 bytes\"); \/\/ Error<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived5  size(8):\r\n   +---\r\n0  | +--- (base class Derived4)\r\n0  | | +--- (base class Empty2)\r\n0  | | | +--- (base class Empty1)\r\n   | | | +---\r\n   | | +---\r\n1  | | +--- (base class Empty3)\r\n   | | +---\r\n   | | &lt;alignment member&gt; (size=3)\r\n4  | | i\r\n   | +---\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Although <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> is applied to <code style=\"font-size: 90%\">Derived5<\/code>, it is not eligible for EBCO because it doesn&#8217;t have any direct empty base classes, so it has no effect.  However, if it is instead applied to the <code style=\"font-size: 90%\">Derived4<\/code> base class, which is eligible for EBCO, both <code style=\"font-size: 90%\">Derived4<\/code> and <code style=\"font-size: 90%\">Derived5<\/code> will have optimal layout:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct __declspec(empty_bases) Derived4 : Empty2, Empty3\r\n{\r\n  int i;\r\n};\r\nstatic_assert(sizeof(Derived4) == 4, \"Derived4 should be 4 bytes\"); \/\/ No Error\r\nstruct Derived5 : Derived4\r\n{\r\n};\r\nstatic_assert(sizeof(Derived5) == 4, \"Derived5 should be 4 bytes\"); \/\/ No Error<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived5  size(4):\r\n   +---\r\n0  | +--- (base class Derived4)\r\n0  | | +--- (base class Empty2)\r\n0  | | | +--- (base class Empty1)\r\n   | | | +---\r\n   | | +---\r\n0  | | +--- (base class Empty3)\r\n   | | +---\r\n0  | | i\r\n   | +---\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>To determine which classes would benefit from <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code>, a new &#8220;undocumented&#8221; <code style=\"font-size: 90%\">\/d1reportClassLayoutChanges<\/code> compiler option has been added that reports the default layout as well as the EBCO layout for any class that would directly benefit from its use.  It is recommended to compile only a single file at a time with this option so as to avoid superfluous output.  Furthermore, this option is unsupported and intended only for informational purposes and should not be used for regular project builds.<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/031916_0236_Optimizingt1.png\" alt=\"\" \/>\n<\/p>\n<p style=\"text-align: center\">\n    <code style=\"font-size: 90%\"><em>Accessing the compiler options for a single file\n    <\/em><\/code>\n<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/031916_0236_Optimizingt2.png\" alt=\"\" \/>\n<\/p>\n<p style=\"text-align: center\">\n    <code style=\"font-size: 90%\"><em>Adding \/d1reportClassLayoutChanges as an additional option\n    <\/em><\/code>\n<\/p>\n<p>The class layout information will be included in the project&#8217;s build log, which is generated in the project&#8217;s Intermediate directory.<\/p>\n<p>Compiling the original examples with <code style=\"font-size: 90%\">\/d1reportClassLayoutChanges<\/code> would output:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">Effective Layout: (Default)\r\nclass Derived3  size(2):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n1  | +--- (base class Empty3)\r\n   | +---\r\n1  | c\r\n   +---\r\nFuture Default Layout: (Empty Base Class Optimization)\r\nclass Derived3  size(1):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n0  | +--- (base class Empty3)\r\n   | +---\r\n0  | c\r\n   +---\r\nEffective Layout: (Default)\r\nclass Derived4  size(8):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n1  | +--- (base class Empty3)\r\n   | +---\r\n   | &lt;alignment member&gt; (size=3)\r\n4  | i\r\n   +---\r\nFuture Default Layout: (Empty Base Class Optimization)\r\nclass Derived4  size(4):\r\n   +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n0  | +--- (base class Empty3)\r\n   | +---\r\n0  | i\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This shows that the effective layout for <code style=\"font-size: 90%\">Derived3<\/code> and <code style=\"font-size: 90%\">Derived4<\/code> is the default layout and that the EBCO layout would cut their sizes in half.  After applying <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> to a class, the output will indicate that its effective layout is the EBCO layout.  Because it is possible for a class to be non-empty with the default layout but be empty with the EBCO layout, you may need to iterate compiling with <code style=\"font-size: 90%\">\/d1reportClassLayoutChanges<\/code> and applying <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> until the entire class hierarchy makes complete use of the EBCO layout.<\/p>\n<p>Due to the aforementioned requirement that all object files and libraries agree on the class layout, <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> can only be applied to classes that you control.  It cannot be applied to classes in the STL nor those that are included in libraries that are not also re-compiled with the EBCO layout.<\/p>\n<p>When the default layout is changed in a future major release of the Visual C++ Compiler Toolset, <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> will no longer have any effect, as every class will make complete use of EBCO.  However, in scenarios involving interop with other languages or dependencies with DLLs that cannot be recompiled, it may be the case that you do not want the layout of a particular class to change when the default is changed.  To address such scenarios, a <code style=\"font-size: 90%\">__declspec(layout_version(19))<\/code> attribute has also been added, which will result in the class layout being identical to the layout in Visual Studio 2015, even after the default layout changes.  This attribute has no effect on code compiled with Visual Studio 2015, but can be applied proactively to inhibit future default class layout changes.<\/p>\n<p>One known issue with the current behavior of <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> is that it may violate a standard requirement that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address:<\/p>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">struct __declspec(empty_bases) Derived6 : Empty1, Empty2\r\n{\r\n  char c;\r\n};<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<colgroup>\n<col style=\"width: 5%\" \/>\n<col style=\"width: 90%\" \/>\n<col style=\"width: 5%\" \/>\n    <\/colgroup>\n<tbody>\n<tr>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<td style=\"background: #EEEEEE;padding: 10px;border-width: 0px\">\n<pre style=\"background: #EEEEEE;margin: 0px;padding: 0px;font-size: 90%\">class Derived6 size(1):\r\n   +---\r\n0  | +--- (base class Empty1)\r\n   | +---\r\n0  | +--- (base class Empty2)\r\n0  | | +--- (base class Empty1)\r\n   | | +---\r\n   | +---\r\n0  | c\r\n   +---<\/pre>\n<\/td>\n<td style=\"padding: 10px;border-width: 0px\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code style=\"font-size: 90%\">Derived6 <\/code>contains two subobjects of type <code style=\"font-size: 90%\">Empty1<\/code>, as there is no virtual inheritance, but they are both laid out at offset 0, which is in violation of the standard. This issue will be fixed in Visual Studio 2015 Update 3; however, doing so will result in such classes having different EBCO layouts in Update 2 and Update 3. Classes that use the default layout won&#8217;t be affected by this change. Therefore, <code style=\"font-size: 90%\">__declspec(empty_bases)<\/code> should not be applied to such classes until Update 3, and should only be applied if compatibility with the Update 2 EBCO layout will not be required. We hope your code can benefit from this improvement to our EBCO support and we look forward to your feedback.<\/p>\n<p>Vinny Romano\nVisual C++ Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C++ Standard has only a handful of requirements regarding how a class is laid out in memory, one of which is that the size of a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Because this requirement only extends to most derived objects, base class [&hellip;]<\/p>\n","protected":false},"author":317,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7941","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>The C++ Standard has only a handful of requirements regarding how a class is laid out in memory, one of which is that the size of a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Because this requirement only extends to most derived objects, base class [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/317"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=7941"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7941\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=7941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=7941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=7941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}