<?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Форум программистов и сисадминов Киберфорум - Блоги - System Release. Автор Убежденный</title>
		<link>https://www.cyberforum.ru/blogs/374580/</link>
		<description>КиберФорум - форум программистов, системных администраторов, администраторов баз данных, компьютерный форум, форум по электронике и бытовой технике, обсуждение софта. Бесплатная помощь в решении задач по программированию и наукам, решение проблем с компьютером, операционными системам</description>
		<language>ru</language>
		<lastBuildDate>Tue, 22 Sep 2026 19:52:34 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://www.cyberforum.ru//cyberstatic.net/images/misc/rss.jpg</url>
			<title>Форум программистов и сисадминов Киберфорум - Блоги - System Release. Автор Убежденный</title>
			<link>https://www.cyberforum.ru/blogs/374580/</link>
		</image>
		<item>
			<title>MS C/C++ Compiler и EBCO при множественном наследовании</title>
			<link>https://www.cyberforum.ru/blogs/374580/4895.html</link>
			<pubDate>Thu, 24 Aug 2017 13:43:46 GMT</pubDate>
			<description>Только что с удивлением узнал, что мой любимый компилятор MS C/C++ Compiler из 
Visual Studio не...</description>
			<content:encoded><![CDATA[<div>Только что с удивлением узнал, что мой любимый компилятор MS C/C++ Compiler из<br />
Visual Studio не умеет выполнять оптимизацию 'Empty Base Class Optimization' (EBCO)<br />
для ситуаций с множественным наследованием.<br />
<br />
EBCO может быть полезна, когда ваш класс наследует несколько пустых классов<br />
(пустой класс - т.е. класс без данных), например для каких-то ограничений или реализаций.<br />
<br />
Пример:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="786124203"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="786124203" style="height: 270px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="de1"><pre class="de1"><span class="kw4">struct</span> NoCopyAssign
<span class="br0">&#123;</span>
&nbsp; &nbsp; NoCopyAssign<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
&nbsp; &nbsp; ~NoCopyAssign<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
&nbsp;
<span class="kw2">private</span><span class="sy4">:</span>
&nbsp; &nbsp; NoCopyAssign<span class="br0">&#40;</span>NoCopyAssign <span class="kw4">const</span> <span class="sy3">&amp;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; NoCopyAssign <span class="sy3">&amp;</span> operator <span class="sy1">=</span> <span class="br0">&#40;</span>NoCopyAssign <span class="kw4">const</span> <span class="sy3">&amp;</span><span class="br0">&#41;</span><span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">struct</span> Test <span class="sy4">:</span>
&nbsp; &nbsp; <span class="kw2">private</span> NoCopyAssign <span class="co1">// Test нельзя копировать и присваивать.</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">void</span> <span class="sy2">*</span> ptr<span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Теперь при попытке сконструировать Test из существующего объекта или выполнить<br />
присваивание одного Test другому будет выдана ошибка компиляции. Все это давно и<br />
хорошо известно. Но каким будет размер Test? Логика подсказывает, что на &quot;нормальных&quot;<br />
компиляторох это будет sizeof (ptr), т.е. sizeof (void *). Так и есть.<br />
<br />
А теперь включим множественное наследование:<br />
<div class="codeblock"><table class="cpp"><thead><tr><td colspan="2" id="71335985"  class="head">C++</td></tr></thead><tbody><tr class="li1"><td><div id="71335985" style="height: 286px" class="codeframe"><table><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="de1"><pre class="de1"><span class="co2">#include &lt;cstdio&gt;</span>
&nbsp;
<span class="kw4">struct</span> c1 <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
<span class="kw4">struct</span> c2 <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
<span class="kw4">struct</span> c3 <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">struct</span> Test <span class="sy4">:</span> c1, c2, c3
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw4">void</span> <span class="sy2">*</span> data<span class="sy4">;</span>
<span class="br0">&#125;</span><span class="sy4">;</span>
&nbsp;
<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp; &nbsp; <span class="kw3">printf</span><span class="br0">&#40;</span><span class="st0">&quot;%u, %u<span class="es1">\r</span><span class="es1">\n</span>&quot;</span>, <span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span><span class="br0">&#41;</span><span class="kw3">sizeof</span> <span class="br0">&#40;</span><span class="kw4">void</span> <span class="sy2">*</span><span class="br0">&#41;</span>, <span class="br0">&#40;</span><span class="kw4">unsigned</span> <span class="kw4">int</span><span class="br0">&#41;</span><span class="kw3">sizeof</span> <span class="br0">&#40;</span>Test<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy4">;</span>
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
<span class="br0">&#125;</span></pre></td></tr></table></div></td></tr></tbody></table></div>Увы, MS C/C++ Compiler дает результат &quot;4, 8&quot; для Win32 и &quot;8, 16&quot; для x64.<br />
Проверено на VS2008 SP1 и на VS2015 Update3, конфигурация Release со всеми оптимизациями.<br />
<br />
Насколько я знаю, GCC и Clang, а, возможно, и Intel тоже, давно умеют и делают EBCO в<br />
таких ситуациях (проверки на codepad, ideone и rextester это подтверждают).<br />
<br />
Единственное, хотя и слабое утешение - в VS2015 Update2 есть малоизвестная опция '__declspec(empty_bases)',<br />
которую со временем хотят сделать поведением по умолчанию. Будем ждать...<br />
<br />
Ссылка в тему:<br />
<br />
<b>Optimizing the Layout of Empty Base Classes in VS2015 Update 2</b><br />
<a rel="nofollow noopener noreferrer" href="https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/" target="_blank" title="https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/">https://blogs.msdn.microsoft.c... pdate-2-3/</a></div>

]]></content:encoded>
			<dc:creator>Убежденный</dc:creator>
			<guid isPermaLink="true">https://www.cyberforum.ru/blogs/374580/4895.html</guid>
		</item>
	</channel>
</rss>
