<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[offsetof - mehrfache vererbung]]></title><description><![CDATA[<p>Hi Leute, ich hab ein Problem: offsetof!<br />
<a href="http://codepad.org/BLvJzg6U" rel="nofollow">http://codepad.org/BLvJzg6U</a></p>
<p>Es geht darum: Ich habe eine wrapper klasse (angenommen Base sei diese), die von CParent eine funktion aufrufen soll. Mit dem o.g. code würde das momentan ohne probleme klappen (ihr könnte gerne eine CParent-Methode erstellen [diese darf aber keine attribute von CParent ansteuern] und diese dann z.b. beim cout &lt;&lt; copy aufrufen). Wenn ich jetzt aber CParent wieder von Base ableite, klappt es nicht mehr, da das offset nicht mehr stimmt.<br />
Wie bekomm ich das richtige offset von m_Sub, wenn ich jetzt noch von Base ableite (also das offset von Base zu m_Sub)?</p>
<p>MfG Krauzi</p>
<p>P.s.: Da sowieso wieder die frage gestellt wird, was ich damit bezwecken will: Ich habe über 200 klassen zu wrappen, von denen alle mindestens 10 constructoren haben (max. ableitungen: 3 mal), ich möchte nicht bei jedem constructor hinschreiben: INITIALIZE(&lt;Klassenname&gt;)!<br />
Da aber alle klassen bereits wegen reflection mit einem macro ausgestattet sind kann ich durch das hinzufügen des im beispiel gezeigten codes diese methode der CParent klasse aufrufen ohne irgendwas im constructor zu ändern.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/273282/offsetof-mehrfache-vererbung</link><generator>RSS for Node</generator><lastBuildDate>Fri, 28 Aug 2026 10:05:41 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/273282.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 03 Sep 2010 16:18:47 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 16:18:47 GMT]]></title><description><![CDATA[<p>Hi Leute, ich hab ein Problem: offsetof!<br />
<a href="http://codepad.org/BLvJzg6U" rel="nofollow">http://codepad.org/BLvJzg6U</a></p>
<p>Es geht darum: Ich habe eine wrapper klasse (angenommen Base sei diese), die von CParent eine funktion aufrufen soll. Mit dem o.g. code würde das momentan ohne probleme klappen (ihr könnte gerne eine CParent-Methode erstellen [diese darf aber keine attribute von CParent ansteuern] und diese dann z.b. beim cout &lt;&lt; copy aufrufen). Wenn ich jetzt aber CParent wieder von Base ableite, klappt es nicht mehr, da das offset nicht mehr stimmt.<br />
Wie bekomm ich das richtige offset von m_Sub, wenn ich jetzt noch von Base ableite (also das offset von Base zu m_Sub)?</p>
<p>MfG Krauzi</p>
<p>P.s.: Da sowieso wieder die frage gestellt wird, was ich damit bezwecken will: Ich habe über 200 klassen zu wrappen, von denen alle mindestens 10 constructoren haben (max. ableitungen: 3 mal), ich möchte nicht bei jedem constructor hinschreiben: INITIALIZE(&lt;Klassenname&gt;)!<br />
Da aber alle klassen bereits wegen reflection mit einem macro ausgestattet sind kann ich durch das hinzufügen des im beispiel gezeigten codes diese methode der CParent klasse aufrufen ohne irgendwas im constructor zu ändern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947886</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947886</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Fri, 03 Sep 2010 16:18:47 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 19:29:00 GMT]]></title><description><![CDATA[<p>Abschnitt 18.1 Absatz 4:</p>
<blockquote>
<p>The macro <strong>offsetof</strong> accepts a restricted set of type arguments in this International Standard. If <strong>type is not a POD</strong> structure or a POD union the <strong>results are undefined</strong>.</p>
</blockquote>
<p>Abschnitt 9 Absatz 4:</p>
<blockquote>
<p>...A <strong>POD-struct</strong> is an <strong>aggregate</strong> that has <strong>no non-static data members of type non-POD-struct</strong>, non-POD-union (or array of such types) or reference, and has no user-declared copy assignment operator and no user-declared destructor...</p>
</blockquote>
<p>Abschnitt 8.5.1 Absatz 1:</p>
<blockquote>
<p>An <strong>aggregate</strong> is an array or a class with no user-declared constructors, no private or protected non-static data members, <strong>no base classes</strong>, and no virtual functions.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1947901</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947901</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 03 Sep 2010 19:29:00 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 17:06:46 GMT]]></title><description><![CDATA[<p>--- was mir nicht gerade weiterhilft. Es muss möglich sein!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947905</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947905</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Fri, 03 Sep 2010 17:06:46 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 17:10:20 GMT]]></title><description><![CDATA[<p>Krauzi schrieb:</p>
<blockquote>
<p>--- was mir nicht gerade weiterhilft. Es muss möglich sein!</p>
</blockquote>
<p>std::string ist kein POD, damit ist CParent kein POD, damit ist offsetof undefiniert. Punkt. Alles andere interessiert nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947907</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947907</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Fri, 03 Sep 2010 17:10:20 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 17:21:27 GMT]]></title><description><![CDATA[<p>in meinem beispiel klappt es aber für's erste.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947913</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947913</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Fri, 03 Sep 2010 17:21:27 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 17:40:22 GMT]]></title><description><![CDATA[<p>Krauzi schrieb:</p>
<blockquote>
<p>in meinem beispiel klappt es aber für's erste.</p>
</blockquote>
<p>Trotzdem kann dir auf deine Frage keiner eine verlässliche Antwort geben. Wenn im Standard steht dass es undefiniert ist, dann geht es mit Standard-C++ eben nicht.</p>
<p>Wie dein verwendeter Compiler die Sache konkret handhabt, ist eine andere Frage. Das müsstest du den Hersteller fragen. Dass dein Beispiel funktioniert kann auch nur Zufall sein. Es ist eben undefiniert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947922</guid><dc:creator><![CDATA[Nukularfüsiker]]></dc:creator><pubDate>Fri, 03 Sep 2010 17:40:22 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 18:28:34 GMT]]></title><description><![CDATA[<p>habs jetzt noch auf mingw oder wie der compiler heißt kompiliert und da hats auch geklappt. Zufall ist das jetzt eher nicht...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947944</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947944</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Fri, 03 Sep 2010 18:28:34 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 18:32:31 GMT]]></title><description><![CDATA[<p>Krauzi schrieb:</p>
<blockquote>
<p>habs jetzt noch auf mingw oder wie der compiler heißt kompiliert und da hats auch geklappt. Zufall ist das jetzt eher nicht...</p>
</blockquote>
<p>wenn etwas undefiniert ist, ists einfach nicht definiert.<br />
wenn 2 compiler zufällig das selbe machen, hat das nichts damit zu tun, was &quot;normalerweise&quot; passiert und heißt auch noch lang nicht, dass es nicht &quot;zufällig&quot; ist...</p>
<pre><code class="language-cpp">void main()
{
;
}
</code></pre>
<p>wetten, ich finde mehr als einen compiler, der das hier compiliert?<br />
ist es dadurch definiert?</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947945</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947945</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Fri, 03 Sep 2010 18:32:31 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 18:37:39 GMT]]></title><description><![CDATA[<p>Krauzi schrieb:</p>
<blockquote>
<p>habs jetzt noch auf mingw oder wie der compiler heißt kompiliert und da hats auch geklappt. Zufall ist das jetzt eher nicht...</p>
</blockquote>
<p>dann heißts, das mehrere compiler ähnliche Dinge machen. Es ändert aber gar nichs daran, dass der Standard ganz klar sagt, dass das jeder Compiler so mchen kann wie er will. Und insbesondere bei Vererbung geht dort alles querbeet durcheinander. Da ändert sich auch gerne mal was zwischen 2 Compilerversionen.</p>
<p>Da kannst du noch so sehr mit dem Fuß aufstampfen und rumflennen, dass es doch gehen muss: der Standard sagt nein. Und der Standard hat in jeder Diskussion das letzte Wort.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947948</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947948</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Fri, 03 Sep 2010 18:37:39 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 18:41:53 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>Da kannst du noch so sehr mit dem Fuß aufstampfen und rumflennen, dass es doch gehen muss: der Standard sagt nein. Und der Standard hat in jeder Diskussion das letzte Wort.</p>
</blockquote>
<p>Außer da wo es geändert wurde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947949</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947949</guid><dc:creator><![CDATA[Stampfi]]></dc:creator><pubDate>Fri, 03 Sep 2010 18:41:53 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 18:49:19 GMT]]></title><description><![CDATA[<p>Gib CParent mal eine virtuelle Funktion (beispielsweise einen Destruktor, wo du doch ableiten willst), und kuck, ob das immer noch hält. Im Übrigen sollte der gcc etwas in dieser Art ausspucken:</p>
<pre><code>test.cc: In constructor »CParent::CSub::CSub()«:
test.cc:23: Warnung: invalid access to non-static data member »CParent::m_Sub«  of NULL object
test.cc:23: Warnung: (vielleicht wurde das Makro »offsetof« falsch verwendet)
</code></pre>
<p>...und du solltest das beachten.</p>
<p>Die Sprache sieht solchen Blödsinn schlicht nicht vor, und es gibt dementsprechend keinen zuverlässigen Weg, das zu machen.</p>
<p>Wenn du dich auf wilde Hacks einlassen willst: --copy erniedrigt copy um sizeof(*copy). Du könntest es mit</p>
<pre><code class="language-cpp">size_t offset = offsetof(CParent, CParent::m_Sub);
CParent* copy = reinterpret_cast&lt;CParent*&gt;(reinterpret_cast&lt;char*&gt;(this) - offset);
</code></pre>
<p>versuchen, aber <strong>ich übernehme keine Garantie dafür</strong>. Sobald das auseinanderfliegt - und das wird es - bist du selbst schuld. Und ganz ehrlich, wenn mir jemand Software andrehen wollte, von der ich wüsste, dass sie solchen Code enthält, könnte der gleich wieder abschwirren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947952</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Fri, 03 Sep 2010 18:49:19 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 20:26:17 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Sorry, dass ich nochmal nachfrage, aber ich verstehe das Problem nicht wirklich...</p>
<blockquote>
<p>Ich habe über 200 klassen zu wrappen, von denen alle mindestens 10 constructoren haben (max. ableitungen: 3 mal), ich möchte nicht bei jedem constructor hinschreiben: INITIALIZE(&lt;Klassenname&gt;)!</p>
</blockquote>
<p>Meintest du da ein template? ... weil als Makro kann ich mir das nicht vorstellen</p>
<blockquote>
<p>Da aber alle klassen bereits wegen reflection mit einem macro ausgestattet sind kann ich durch das hinzufügen des im beispiel gezeigten codes diese methode der CParent klasse aufrufen ohne irgendwas im constructor zu ändern.</p>
</blockquote>
<p>Ich kann in dem Code keine Initialisierung entdecken, sondern nur den Versuch erkennen den Pointer des CParent-Objektes aus dem Member heraus zu bekommen (und wie @seldon schon sagte funktioniert das so nicht immer) ...</p>
<p>Wenn es um Initialisierung geht, kannst du ja templates und deren Spezialisierung benutzen.</p>
<pre><code class="language-cpp">template&lt;class T&gt; struct Initer;

template&lt;&gt; struct Initer&lt;Base&gt; : public Base
{
  Initer() // Initer&lt;Base&gt; ist ja zugleich auch Base ;)
  {
    this-&gt;attr1 = 12;
    this-&gt;attr2 = 0;
    this-&gt;attr3 = &quot;Hello World&quot;;
  }
};
template&lt;&gt; struct Initer&lt;Base2&gt; : public Base2
{
  Initer() { ... }
};
...
Base * ptrBase = new Initer&lt;Base&gt;;
Base2 * ptrBase2 = new Initer&lt;Base2&gt;;
</code></pre>
<p>cu <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947976</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947976</guid><dc:creator><![CDATA[xor]]></dc:creator><pubDate>Fri, 03 Sep 2010 20:26:17 GMT</pubDate></item><item><title><![CDATA[Reply to offsetof - mehrfache vererbung on Fri, 03 Sep 2010 20:40:45 GMT]]></title><description><![CDATA[<p>@Krauzi:<br />
Ich verstehe nicht genau was du machen willst, aber es klingt verflixt danach als ob es Murks wäre.</p>
<p>Vorschlag: zeig mal den Code ohne <code>offsetof()</code> , den du vermeiden willst, der aber sicher funktionieren würde. Also die triviale Implementierung.</p>
<p>Vielleicht kann dir dann jmd. einen besseren Vorschlag als den von dir geplanten Hack machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1947984</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1947984</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 03 Sep 2010 20:40:45 GMT</pubDate></item></channel></rss>