<?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[reinterpret_cast und wieder zurück immer möglich?]]></title><description><![CDATA[<p>Hi,</p>
<p>um Daten weiterzuleiten, möchte ich diese generisch abspeichern.<br />
Also nur Zeiger auf die Daten und dann wieder zurück konvertieren.<br />
Z.b. möchte ich einen Zeiger auf Objekte in ein void* abspeichern.<br />
Also mit <code>reinterpret_cast</code> nach <code>void*</code> und dann wieder zurück zum Original Typ.</p>
<p>In etwa so:</p>
<pre><code>class dummy_class
{
};
typedef void (*void_func_ptr)();
typedef void (dummy_class::*void_mem_func_ptr)();
typedef void* (dummy_class::*void_mem_obj_ptr);

union data_container
{
    void*               obj_ptr;      // Stores a pointer to an object
    void_mem_obj_ptr    mem_obj_ptr;  // Stores a pointer to a member object
    void_func_ptr       func_ptr;     // Stores a pointer to a function
    void_mem_func_ptr   mem_func_ptr; // Stores a pointer to a member function
};
</code></pre>
<p>Der Standard sagt dazu auch etwas in §5.2.10.10<br />
So wie ich das jetzt verstanden habe sollte das auch alles funktionieren.<br />
Nur beim konvertieren eines &quot;pointer to a data member&quot; bin ich unschlüssig, das verstehe ich nicht ganz:</p>
<blockquote>
<p>converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data<br />
member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1)<br />
and back to its original type yields the original pointer to member value.</p>
</blockquote>
<p>Kann mir jemand genau erklären was mit <em>alignment requirements</em> gemeint ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/331475/reinterpret_cast-und-wieder-zurück-immer-möglich</link><generator>RSS for Node</generator><lastBuildDate>Fri, 01 May 2026 14:59:32 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/331475.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 02 Mar 2015 20:54:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Mon, 02 Mar 2015 20:54:36 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>um Daten weiterzuleiten, möchte ich diese generisch abspeichern.<br />
Also nur Zeiger auf die Daten und dann wieder zurück konvertieren.<br />
Z.b. möchte ich einen Zeiger auf Objekte in ein void* abspeichern.<br />
Also mit <code>reinterpret_cast</code> nach <code>void*</code> und dann wieder zurück zum Original Typ.</p>
<p>In etwa so:</p>
<pre><code>class dummy_class
{
};
typedef void (*void_func_ptr)();
typedef void (dummy_class::*void_mem_func_ptr)();
typedef void* (dummy_class::*void_mem_obj_ptr);

union data_container
{
    void*               obj_ptr;      // Stores a pointer to an object
    void_mem_obj_ptr    mem_obj_ptr;  // Stores a pointer to a member object
    void_func_ptr       func_ptr;     // Stores a pointer to a function
    void_mem_func_ptr   mem_func_ptr; // Stores a pointer to a member function
};
</code></pre>
<p>Der Standard sagt dazu auch etwas in §5.2.10.10<br />
So wie ich das jetzt verstanden habe sollte das auch alles funktionieren.<br />
Nur beim konvertieren eines &quot;pointer to a data member&quot; bin ich unschlüssig, das verstehe ich nicht ganz:</p>
<blockquote>
<p>converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data<br />
member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1)<br />
and back to its original type yields the original pointer to member value.</p>
</blockquote>
<p>Kann mir jemand genau erklären was mit <em>alignment requirements</em> gemeint ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444974</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444974</guid><dc:creator><![CDATA[Nash26]]></dc:creator><pubDate>Mon, 02 Mar 2015 20:54:36 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Mon, 02 Mar 2015 21:18:37 GMT]]></title><description><![CDATA[<p>Jeder Typ T hat einen &quot;alignment requirement&quot; Wert.<br />
Das ist einfach ne Zahl. Und durch diese Zahl muss die Adresse an der sich ein <code>T</code> -Objekt befinden darf ohne Rest teilbar sein.</p>
<p>Auf einigen Systemen dürfen 4-Byte Integer z.B. nur an durch 4 teilbaren Adressen liegen. Weil die CPU sie nur von solchen Adressen lesen bzw. auf solche Adressen schreiben kann. Auf so einen System wäre der &quot;alignment requirement&quot; Wert eines 4-Byte Integers also 4.</p>
<p>Siehe auch<br />
<a href="http://en.cppreference.com/w/cpp/language/object#Alignment" rel="nofollow">http://en.cppreference.com/w/cpp/language/object#Alignment</a></p>
<p>ps:</p>
<blockquote>
<pre><code class="language-cpp">typedef void* (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Ich behaupte mal da ist ein * zuviel.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444975</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444975</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 02 Mar 2015 21:18:37 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Mon, 02 Mar 2015 21:51:27 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>ps:</p>
<blockquote>
<pre><code class="language-cpp">typedef void* (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Ich behaupte mal da ist ein * zuviel.</p>
</blockquote>
<p>Ein Member kann nicht den Typ void haben.<br />
Allerdings ist void* tatsächlich nicht geeignet, eben wegen der alignment-Voraussetzungen. char, mithin</p>
<pre><code class="language-cpp">char dummy_class::* mem_obj_ptr;
</code></pre>
<p>wäre angebracht.</p>
<p>Im Übrigen sollten Konvertierungen von und nach void* üblicherweise nicht mittels reinterpret_cast durchgeführt werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444979</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444979</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 02 Mar 2015 21:51:27 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Mon, 02 Mar 2015 22:32:15 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a> erklär mir bitte warum ein <code>char</code> verwendet werden muss, das verstehe ich nicht:</p>
<pre><code>typedef char (dummy_class::*void_mem_obj_ptr);
</code></pre>
<p>Ich kann kein <code>static_cast</code> verwenden, im standard sind diese Operationen nur für <code>reinterpret_cast</code> definiert. Siehe §5.2.10</p>
<p>Kannst du selbst mit g++ ausprobieren, ich bekomme auch einen compile fehler.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444982</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444982</guid><dc:creator><![CDATA[Nash26]]></dc:creator><pubDate>Mon, 02 Mar 2015 22:32:15 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 00:25:17 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>ps:</p>
<blockquote>
<pre><code class="language-cpp">typedef void* (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Ich behaupte mal da ist ein * zuviel.</p>
</blockquote>
<p>Ein Member kann nicht den Typ void haben.<br />
Allerdings ist void* tatsächlich nicht geeignet, eben wegen der alignment-Voraussetzungen.</p>
</blockquote>
<p>Hm. Ich hab' einfach mal angenommen dass für Member-Pointer was void angeht die selben Regeln gelten wie für normale Zeiger.<br />
Ein Objekt kann ja auch nicht den Typ void haben, trotzdem gibt es void-Pointer. Und diese sind auf geeignet auf alles zu zeigen, egal was für ein Alignment es hat.<br />
Wenn für Member-Pointer andere Regeln gelten würde ich das zumindest als verwirrend bezeichnen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2444990</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2444990</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 03 Mar 2015 00:25:17 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 07:09:23 GMT]]></title><description><![CDATA[<p>Nash26 schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a> erklär mir bitte warum ein <code>char</code> verwendet werden muss, das verstehe ich nicht:</p>
<pre><code>typedef char (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Weil char die geringsten alignment requirements aller Typen hat.</p>
<p>Nash26 schrieb:</p>
<blockquote>
<p>Ich kann kein <code>static_cast</code> verwenden, im standard sind diese Operationen nur für <code>reinterpret_cast</code> definiert. Siehe §5.2.10</p>
<p>Kannst du selbst mit g++ ausprobieren, ich bekomme auch einen compile fehler.</p>
</blockquote>
<p>Ich habe meiner vorherigen Antwort diesbezgl. nichts hinzuzufügen. Evtl. solltest du nochmal lesen, was du selbst zuvor geschrieben hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445007</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445007</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Mar 2015 07:09:23 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 07:13:36 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>ps:</p>
<blockquote>
<pre><code class="language-cpp">typedef void* (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Ich behaupte mal da ist ein * zuviel.</p>
</blockquote>
<p>Ein Member kann nicht den Typ void haben.<br />
Allerdings ist void* tatsächlich nicht geeignet, eben wegen der alignment-Voraussetzungen.</p>
</blockquote>
<p>Hm. Ich hab' einfach mal angenommen dass für Member-Pointer was void angeht die selben Regeln gelten wie für normale Zeiger.<br />
Ein Objekt kann ja auch nicht den Typ void haben, trotzdem gibt es void-Pointer. Und diese sind auf geeignet auf alles zu zeigen, egal was für ein Alignment es hat.<br />
Wenn für Member-Pointer andere Regeln gelten würde ich das zumindest als verwirrend bezeichnen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Zeiger auf Member sind keine Zeiger.<br />
Übrigens ist der Standard hier auch sprachlich konsistent<br />
void* ist eine 'object pointer' aber kein 'pointer to object'.<br />
Auch zeigt void* auf nichts, schließlich kann void nicht dereferenziert werden.<br />
Kurz: void ist sowieso speziell.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445009</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445009</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Mar 2015 07:13:36 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 08:53:33 GMT]]></title><description><![CDATA[<p>Und warum kompiliert dann</p>
<pre><code>struct A {
    using type = A(A::*);
};
</code></pre>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445019</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 03 Mar 2015 08:53:33 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 17:52:17 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Ich habe meiner vorherigen Antwort diesbezgl. nichts hinzuzufügen. Evtl. solltest du nochmal lesen, was du selbst zuvor geschrieben hast.</p>
</blockquote>
<p>Meinen Hinweis mit dem static_cast hast du gelesen? Den kann man dafür nicht verwenden.</p>
<p>Ok, aber ich verstehe Deine Antwort trotz mehrmaligen lesen immer noch nicht.<br />
Warum char und nicht void*.</p>
<p>Hat es jemand anderes vielleicht verstanden und kann es mir erklären?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445076</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445076</guid><dc:creator><![CDATA[Nash26]]></dc:creator><pubDate>Tue, 03 Mar 2015 17:52:17 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 21:59:59 GMT]]></title><description><![CDATA[<p>Nash26 schrieb:</p>
<blockquote>
<p>Z.b. möchte ich einen Zeiger auf Objekte in ein void* abspeichern.<br />
Also mit <code>reinterpret_cast</code> nach <code>void*</code> und dann wieder zurück zum Original Typ.</p>
</blockquote>
<p>camper schrieb:</p>
<blockquote>
<p>Im Übrigen sollten Konvertierungen von und nach void* üblicherweise nicht mittels reinterpret_cast durchgeführt werden.</p>
</blockquote>
<p>Nash26 schrieb:</p>
<blockquote>
<p>Ich kann kein <code>static_cast</code> verwenden, im standard sind diese Operationen nur für <code>reinterpret_cast</code> definiert. Siehe §5.2.10</p>
</blockquote>
<p>Beipiele. bringen. Ich bin extrem emfindlich, wenn zu Widersprüchen keine nachvollziehbare Begründung geliefert wird.<br />
Natürlich wird reinterpret_cast erforderlich, wenn es um Zeiger auf Member (oder Funktionszeiger) geht. Davon ist in diesen Sätzen aber keine Rede.</p>
<p>Nash26 schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a> erklär mir bitte warum ein <code>char</code> verwendet werden muss, das verstehe ich nicht:</p>
<pre><code>typedef char (dummy_class::*void_mem_obj_ptr);
</code></pre>
</blockquote>
<p>Ich zitiere deine Quelle:</p>
<blockquote>
<p>converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data<br />
member of Y of type T2” (<strong>where the alignment requirements of T2 are no stricter than those of T1</strong>)<br />
and back to its original type yields the original pointer to member value.</p>
</blockquote>
<p>was liegt näher als für T2 einen Typ mit den geringsten Alignmentvoraussetzungen zu verwenden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445131</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445131</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 03 Mar 2015 21:59:59 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Tue, 03 Mar 2015 23:52:55 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a><br />
Dass unter diesen Voraussetzungen <code>char</code> gehen muss ist (mir) klar.<br />
Nur nicht warum <code>void</code> nicht gehen soll.</p>
<p>Dass ein &quot;Zeiger auf Member&quot; nicht das selbe ist wie ein Zeiger, ist auch klar.<br />
Der Unterschied ist aber mMn. minimal.<br />
Beide kann man als Offset verstehen. Bei einem normalen Zeiger ist die Basisadresse dabei halt konstant, bei einem &quot;Zeiger auf Member&quot; ... nicht.</p>
<p>Bei beiden sind Alignment-Requirements wichtig. Bei beiden ist es so dass <code>void</code> eigentlich keinen Sinn macht (weil es weder <code>void</code> Objekte noch <code>void</code> Member gibt), aber schön als Joker verwendet werden kann.<br />
Für &quot;normale&quot; Zeiger erlaubt das Standard die Verwendung von <code>void</code> explizit. Ob der Standard das für &quot;Zeiger auf Member&quot; erlaubt, weiss ich nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445150</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 03 Mar 2015 23:52:55 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Wed, 04 Mar 2015 12:52:35 GMT]]></title><description><![CDATA[<blockquote>
<p>8.3.3/3<br />
A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or “<em>cv</em> void.”</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2445214</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445214</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 04 Mar 2015 12:52:35 GMT</pubDate></item><item><title><![CDATA[Reply to reinterpret_cast und wieder zurück immer möglich? on Wed, 04 Mar 2015 14:02:38 GMT]]></title><description><![CDATA[<p>Ah, OK, danke.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2445233</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2445233</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 04 Mar 2015 14:02:38 GMT</pubDate></item></channel></rss>