<?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[&amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert?]]></title><description><![CDATA[<p>Hi!</p>
<p>Wollt nur mal wissen, ob das geht (UB oder nicht):</p>
<pre><code class="language-cpp">struct Context
{
	OVERLAPPED overlapped;
	unsigned int type;
};

OVERLAPPED* g_overlapped;

void Set(OVERLAPPED* overlapped)
{
	g_overlapped = overlapped;
}

void Get(OVERLAPPED** overlapped)
{
	*overlapped = g_overlapped;
}

int main()
{
	{
		Context* context = new Context;

		cout &lt;&lt; context &lt;&lt; endl; // 00345268

		Set((OVERLAPPED*)context);
	}

	{
		Context* context;

		Get((OVERLAPPED**)&amp;context); // Diese Casterei ist angeblich Blödsinn, funktioniert aber! Ich bekomme also wieder die richtige Adresse (Visual Studio 2008)

		cout &lt;&lt; context &lt;&lt; endl; // 00345268 identisch
	}
}
</code></pre>
<p>Es wird 2x die selbe Adresse ausgegeben. Hintergrund ist, dass ich <a href="http://msdn.microsoft.com/en-us/library/aa364986" rel="nofollow">GetQueuedCompletionStatus</a> richtig benutzen möchte. Aber bin mir nicht ganz sicher, ob das so OK ist.<br />
Man könnte Set() mit zB. WSARecv() vergleichen und Get() mit GetQueuedCompletionStatus().</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/281733/quot-pointerfrickeleien-quot-ist-das-undefiniert</link><generator>RSS for Node</generator><lastBuildDate>Sun, 23 Aug 2026 12:19:29 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/281733.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Feb 2011 22:06:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 22:06:42 GMT]]></title><description><![CDATA[<p>Hi!</p>
<p>Wollt nur mal wissen, ob das geht (UB oder nicht):</p>
<pre><code class="language-cpp">struct Context
{
	OVERLAPPED overlapped;
	unsigned int type;
};

OVERLAPPED* g_overlapped;

void Set(OVERLAPPED* overlapped)
{
	g_overlapped = overlapped;
}

void Get(OVERLAPPED** overlapped)
{
	*overlapped = g_overlapped;
}

int main()
{
	{
		Context* context = new Context;

		cout &lt;&lt; context &lt;&lt; endl; // 00345268

		Set((OVERLAPPED*)context);
	}

	{
		Context* context;

		Get((OVERLAPPED**)&amp;context); // Diese Casterei ist angeblich Blödsinn, funktioniert aber! Ich bekomme also wieder die richtige Adresse (Visual Studio 2008)

		cout &lt;&lt; context &lt;&lt; endl; // 00345268 identisch
	}
}
</code></pre>
<p>Es wird 2x die selbe Adresse ausgegeben. Hintergrund ist, dass ich <a href="http://msdn.microsoft.com/en-us/library/aa364986" rel="nofollow">GetQueuedCompletionStatus</a> richtig benutzen möchte. Aber bin mir nicht ganz sicher, ob das so OK ist.<br />
Man könnte Set() mit zB. WSARecv() vergleichen und Get() mit GetQueuedCompletionStatus().</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017577</guid><dc:creator><![CDATA[Hi]]></dc:creator><pubDate>Sun, 06 Feb 2011 22:06:42 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 23:04:43 GMT]]></title><description><![CDATA[<p>An dem casting sehe ich eigentlich kein Problem. Casts sind ja nur da, um das Typsystem zu überlisten. Schlussendlich ist es aber kein Problem was für ein Typ ein Objekt mal hatte, solange die Grösseninformationen immer gleich sind. Und da du hier immer Zeiger hast ist garantiert, dass die alle gleich gross sind. Also kann man Zeiger beliebig umhercasten.</p>
<p>Wie kommst du darauf, dass es Blödsinn sein soll? (klar casting sollte man vermeiden, wenn möglich, aber oftmals in Verbindung mit anderen API's ist man gezwungen die zu benutzen; insbesondere bei der WinAPI).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017597</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 06 Feb 2011 23:04:43 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 23:18:40 GMT]]></title><description><![CDATA[<p><a href="http://www.c-plusplus.net/forum/273353-10" rel="nofollow">http://www.c-plusplus.net/forum/273353-10</a><br />
1. Post <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13960">@hustbaer</a><br />
Und weiter unten der Post von <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/35992">@Martin</a> Richter</p>
<p>Zunächst gings um ein vererbtes OVERLAPPED, dann aber um einen Member.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017602</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017602</guid><dc:creator><![CDATA[Hi]]></dc:creator><pubDate>Sun, 06 Feb 2011 23:18:40 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 23:31:06 GMT]]></title><description><![CDATA[<p>Hmm. Ja, also das mit dem Doppelzeiger bin ich mir nicht ganz sicher. Ich glaube die Dereferenzierung in Get ist nicht definiert, weil der Typ ja nicht korrekt ist.<br />
So wie es hustbaer aber zeigt ist sollte es wohldefiniert sein.<br />
Casten und rumschieben von Zeigern sollte aber nie ein Problem sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017606</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017606</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 06 Feb 2011 23:31:06 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 23:33:38 GMT]]></title><description><![CDATA[<p>Jo, aber Context ist ja eigentlich vom Speicher her bis hin zu sizeof(OVERLAPPED) gleich... deshalb denke ich mir, dass es kein Problem ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017608</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017608</guid><dc:creator><![CDATA[Hi]]></dc:creator><pubDate>Sun, 06 Feb 2011 23:33:38 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Sun, 06 Feb 2011 23:55:30 GMT]]></title><description><![CDATA[<p>5.3.1/1 schrieb:</p>
<blockquote>
<p>The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an<br />
object type, or a pointer to a function type and the result is an lvalue referring to the object or function to<br />
which the expression points.</p>
</blockquote>
<p>Das verletzt du mit der dereferenzierung, weil der Ausdruck, den du dereferenzierst nicht auf ein Objekt des Typen zeigt, sondern auf etwas anderes (in dem Falle wieder ein Zeiger).</p>
<p>Wenn du es so machst, wie hustbaer zeigt, dann bist du da allerdings auf der sicheren Seite. Der cast nach Context ist dann wieder sicher Ok.</p>
<p>Wahrscheinlich wird deine Variante schon meistens gehen, aber es ist halt trotzdem nicht sicher.<br />
Dass die Dereferenzierung nicht erlaubt ist macht auch Sinn, weil ein Zeiger ist nie gefährlich bis er einmal benutzt wird und dazu muss er immer dereferenziert werden und dann muss der Typ stimmen, sonst hast du den Salat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017613</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017613</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sun, 06 Feb 2011 23:55:30 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 00:58:28 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">Context* context;
Get((OVERLAPPED**)&amp;context);
</code></pre>
<p>Das ist laut Standard nicht OK.<br />
Dass es mit den meisten Implementierungen trotzdem funktionieren wird, ist eine andere Sache. Es gibt auch einige APIs die sich darauf verlassen dass soetwas funktioniert, z.B. die COM Funktionen unter Windows (CoCreateInstance, IUnknown::QueryInterface uvm.). Nur deswegen muss man es ja nicht nachmachen.</p>
<p>Warum es nicht OK ist: Zeiger auf unterschiedliche Typen können unterschiedlich aussehen.</p>
<p>Stell dir eine C++ Implementierung für eine 32 Bit CPU vor, die nur 32 Bit Worte einzeln adressieren kann. (BTW: So eine CPU kann dann, trotz beschränkung auf 32 Bit, 16 BG RAM adressieren.)<br />
Wie soll jetzt ein Zeiger auf ein &quot;char&quot; aussehen? Nun, laut C++ Standard ist es OK wenn ein &quot;char&quot; 32 Bit hat, also könnte eine C++ Implementierung einfach definieren: char, short und int haben alle 32 Bit - und die Sache wäre geritzt.<br />
Bloss verschwendet das ziemlich viel Speicher. Also verwendet die C++ Implementierung 8 Bit grosse chars, und verwendet zwei 32 Bit Wörter für char Zeiger: ein Wort für die Adresse des 32 Bit Wortes in dem sich der &quot;char&quot; befindet, und noch ein Wort für die Nummer des &quot;char&quot; in diesem Wort (0-3).</p>
<p>Ebenso sind dann Zeiger auf short 2 Worte gross, bzw. auch Zeiger auf alle Typen deren Alignment kleiner 4 Byte ist. Also ggf. auch Structs oder Klassen.</p>
<p>Angenommen OVERLAPPED wäre 2 Byte gross. Ein OVERLAPPED Zeiger würde dann aus 2 Worten bestehen.<br />
Context enthält nun aber zusätzlich zu einem OVERLAPPED Member noch einen int. Nehmen wir an der int hat die üblichen 4 Byte, dann braucht ein &quot;Context&quot; min. 6 Byte. Sagen wir weiter die C++ Implementierung definiert dass alles was zwischen 5 und 7 Byte gross ist, mit Padding auf 8 Byte &quot;aufgewüllt&quot; wird. sizeof(Context) ist also 8, und alignof(Context) wäre sagen wir 4.<br />
Und schwupps, ein &quot;Zeiger auf Context&quot; braucht nur mehr aus einem Wort zu bestehen (da alignof(Context) ja 4 ist, muss das 2. Wort immer 0 sein, und kann daher weggelassen werden).</p>
<p>Resultat: ein &quot;Zeiger auf OVERLAPPED&quot; (T*) und ein &quot;Zeiger auf Context&quot; (U*) sehen im Speicher ganz unterschiedlich aus. Daher kann man auch nicht einen T** in einen U** casten, und erwarten, dass dabei etwas sinnvolles rauskommt. Das wäre wie einen std::vector&lt;char&gt;* in einen std::string* zu casten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017617</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017617</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 07 Feb 2011 00:58:28 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 07:12:04 GMT]]></title><description><![CDATA[<p>Nicht ablenkend gemeinter Applaus für diese informationsreiche Erklärung. <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/2017646</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017646</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Mon, 07 Feb 2011 07:12:04 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 10:24:16 GMT]]></title><description><![CDATA[<p>Hmmm...ganz so einfach ist es nicht. Eigentlich ist es mit allen Konsequenzen (strict aliasing!) sogar ziemlich kompliziert.</p>
<p>Also: Für POD-Structs (und auch nur für die) ist garantiert, dass die Speicheradresse des gesamten Structs und die seines ersten Members identisch sind - padding kommt nicht am Anfang eines structs. Dieser Umstand wird in C gern genutzt, um objektorientierte Vererbung per pointer punning nachzustellen - genau das, was du da vorhast. Im Standard:</p>
<p>ISO/IEC 14882:2003 9.2 (17) schrieb:</p>
<blockquote>
<p>A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]</p>
</blockquote>
<p>Natürlich musst du aber wie ein Adler darauf achten, dass du diesen Zeiger, wenn du ihn zurückcastest, nicht in einen Typ zurückcastest, der mit dem gespeicherten nicht Layout-kompatibel ist. Layout-Kompatibilität definiert wie folgt:</p>
<p>ISO/IEC 14482:2003 9.2 (14-16) schrieb:</p>
<blockquote>
<p>14 Two POD-struct (clause 9) types are layout-compatible if they have the same number of nonstatic data members, and corresponding nonstatic data members (in order) have layout-compatible types (3.9).</p>
<p>15 Two POD-union (clause 9) types are layout-compatible if they have the same number of nonstatic data members, and corresponding nonstatic data members (in any order) have layout-compatible types (3.9).</p>
<p>16 If a POD-union contains two or more POD-structs that share a common initial sequence, and if the POD-union object currently contains one of these POD-structs, it is permitted to inspect the common initial part of any of them. Two POD-structs share a common initial sequence if corresponding members have layout-compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.</p>
</blockquote>
<p>Und als ob das noch nicht fummelig genug wäre, gibt es strict-aliasing-Regeln nach 3.10 (15):</p>
<p>ISO/IEC 14882:2003 3.10 (15) schrieb:</p>
<blockquote>
<p>If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined <sup>48)</sup>:</p>
<p>— the dynamic type of the object,<br />
— a cv-qualified version of the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,<br />
<strong>— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union),</strong><br />
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,<br />
— a char or unsigned char type.</p>
<p><sup>48)</sup> The intent of this list is to specify those circumstances in which an object may or may not be aliased.</p>
</blockquote>
<p>Das ist für den Optimierer wichtig. Beispielsweise darf der in einer Funktion der Form</p>
<pre><code class="language-cpp">void foo(bar *p, baz *q) {
  // ...
}
</code></pre>
<p>mit zwei POD-Typen bar und baz davon ausgehen, dass p und q nicht auf das gleiche Objekt zeigen. Das kann in Verbindung mit type punning, wenn man nicht sehr vorsichtig ist, zu sehr langen und frustrierenden Debugging-Sessions führen.</p>
<p>Insgesamt bedeutet das beispielsweise:</p>
<pre><code class="language-cpp">struct foo {
  OVERLAPPED o;
  int x;
};

struct bar {
  OVERLAPPED o;
  short x;
};

// ...

foo f;
OVERLAPPED *p = reinterpret_cast&lt;OVERLAPPED*&gt;(&amp;f);
bar *q = reinterpret_cast&lt;bar*&gt;(p);

q-&gt;o; // Undefiniert!

// Aber:
union baz { foo f; bar b; } *r = reinterpret_cast&lt;baz*&gt;(p);

r-&gt;b.o; // OK
r-&gt;b.x; // Undefiniert!

bar *s = &amp;r-&gt;b;
s-&gt;o; // Undefiniert!

foo *t = &amp;r-&gt;f;
t-&gt;o; // OK
</code></pre>
<p>Das ganze ist natürlich ein Wespennest, dass man am besten durch eine vernünftige Klassenhierarchie vollständig umgeht. Spricht etwas dagegen, einen Zeiger auf eine Basisklasse zu speichern und damit zu arbeiten? Dann kriegst du später auch keine Probleme damit, den Kram wieder zu löschen - momentan habe ich Schwierigkeiten zu sehen, wie du g_overlapped in definierter Weise wieder loswerden willst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017712</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017712</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Mon, 07 Feb 2011 10:24:16 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 10:48:39 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">Context* context;
Get((OVERLAPPED**)&amp;context);
</code></pre>
</blockquote>
<p>Warum macht man sowas?</p>
<pre><code class="language-cpp">Context* context;
Get(&amp;((OVERLAPPED*)context));
</code></pre>
<p>Das wäre doch genau das, was man oben erreichen will, nur dass das Verhalten<br />
definiert ist.</p>
<p>Oder sehe ich das falsch?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017721</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017721</guid><dc:creator><![CDATA[?????]]></dc:creator><pubDate>Mon, 07 Feb 2011 10:48:39 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 10:56:46 GMT]]></title><description><![CDATA[<p>Dankesehr für die Erklärungen!</p>
<p>So ganz verstehe ich es derzeit leider noch nicht. Besonders die Beispiele von @seldon ...</p>
<p>Da ich eh nur mit Windows arbeite, könnte ich es dann doch so stehen lassen.</p>
<p>@?????<br />
error C2102: '&amp;' requires l-value</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017725</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017725</guid><dc:creator><![CDATA[Hi]]></dc:creator><pubDate>Mon, 07 Feb 2011 10:56:46 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 15:16:14 GMT]]></title><description><![CDATA[<p>Du kannst nur die Adresse von Objekten holen, die auch eine haben.<br />
Beispiel:</p>
<pre><code class="language-cpp">int* answer_to_the_universe = &amp;42;
</code></pre>
<p>Wird nicht funktionieren, du musst 42 in einer Variablen Speichern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017845</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017845</guid><dc:creator><![CDATA[314159265358979]]></dc:creator><pubDate>Mon, 07 Feb 2011 15:16:14 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 20:26:23 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">Context* context;
Get((OVERLAPPED**)&amp;context);
</code></pre>
<p>Das ist laut Standard nicht OK.<br />
Dass es mit den meisten Implementierungen trotzdem funktionieren wird, ist eine andere Sache. Es gibt auch einige APIs die sich darauf verlassen dass soetwas funktioniert, z.B. die COM Funktionen unter Windows (CoCreateInstance, IUnknown::QueryInterface uvm.).</p>
</blockquote>
<p>So, ich muss mich hier mal selbst korrigieren.<br />
CoCreateInstance etc. sind vollkommen OK, so lange man sie richtig verwendet.<br />
OK:</p>
<pre><code class="language-cpp">void* isv = 0;
HRESULT hr = CoCreateInstance(...., &amp;isv);
ISomething* is = static_cast&lt;ISomething*&gt;(isv);
</code></pre>
<p>Nicht OK:</p>
<pre><code class="language-cpp">ISomething* is = 0;
HRESULT hr = CoCreateInstance(...., reinterpret_cast&lt;void**&gt;(&amp;is));
</code></pre>
<p>Die API an sich ist also in Ordnung, nur die Art wie sie meistens verwendet wird nicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2017973</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2017973</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 07 Feb 2011 20:26:23 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 21:52:11 GMT]]></title><description><![CDATA[<p>Interessieren würde mich, ob es mit VS2008 definiert ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2018017</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2018017</guid><dc:creator><![CDATA[Hi]]></dc:creator><pubDate>Mon, 07 Feb 2011 21:52:11 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Mon, 07 Feb 2011 21:58:35 GMT]]></title><description><![CDATA[<p>Hi schrieb:</p>
<blockquote>
<p>Interessieren würde mich, ob es mit VS2008 definiert ist.</p>
</blockquote>
<p>Wieso willst du es unbedingt so lassen? Schreib es um, so dass du kein undefiniertes Verhalten verwenden musst, anstatt dir den Kopf darüber zu zerbrechen ob eine bestimmte Implementierung das Verhalten definiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2018018</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2018018</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 07 Feb 2011 21:58:35 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Tue, 08 Feb 2011 13:56:46 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">void* isv = 0;
HRESULT hr = CoCreateInstance(...., &amp;isv);
ISomething* is = static_cast&lt;ISomething*&gt;(isv);
</code></pre>
</blockquote>
<p>Wer Schreibarbeit sparen will, benutzt einen kleinen Proxy:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class APIfy
{
public:
    APIFy(T*&amp; p) : p_( p ), v_( p ) {}
    ~APIFy() { p_ = static_cast&lt; T* &gt;( v_ ); }
    void** operator() { return &amp;v_; }
private:
    void operator=(APIfy&amp;);
    T*&amp; p_;
    void* v_;
};
template &lt;typename T&gt;
APIfy&lt;T&gt; apify(T*&amp; p) { return APIfy&lt;T&gt;( p ); }

...

ISomething* is = 0;
HRESULT hr = CoCreateInstance(...., apify(is));
</code></pre>
<p>Vorteil hier, dass man ggf. bereits vorhandenen Code durch einfaches Suchen&amp;Ersetzen korrigieren kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2018255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2018255</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 08 Feb 2011 13:56:46 GMT</pubDate></item><item><title><![CDATA[Reply to &amp;quot;Pointerfrickeleien&amp;quot; - Ist das undefiniert? on Tue, 08 Feb 2011 21:54:57 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 />
So einen Proxy verwenden wir in der Arbeit auch, nur dass er statt rohen Zeiger mit boost::intrusive_ptr&lt;T&gt; arbeitet <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/2018512</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2018512</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 08 Feb 2011 21:54:57 GMT</pubDate></item></channel></rss>