<?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[Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt?]]></title><description><![CDATA[<p>Hallo,<br />
darf man laut Standard einen Typ, der einen Konstruktor definiert, in einer union verwenden? Hier ein Beispiel:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector3
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
    Vector3() {}
    Vector3(T value) : x(value), y(value), z(value) {}
    Vector3(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

template&lt;typename T&gt;
class Line
{
    union
    {
        struct{ Vector3&lt;T&gt; a, b; };
        struct
        {
            Vector3&lt;T&gt; direction;
            double length;
        };
    };
};

int main()
{
    Line&lt;float&gt; line;
}
</code></pre>
<p>VC++ 8 kompiliert es, aber</p>
<p>g++ schrieb:</p>
<blockquote>
<p>error: member x with constructor not allowed in union</p>
</blockquote>
<ul>
<li>Welcher Compiler verhält sich hier richtig?</li>
<li>Ist diese Einschränkung wirklich so wichtig, oder wäre es nicht wichtiger, wenn der Compiler meckern (zumindest warnen) würde, dass man auf ein Element der union lesend zugreift, obwohl sich der letzte Schreibzugriff auf ein anderes bezog?</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/topic/151866/ist-ein-typ-mit-konstruktor-in-einer-quot-union-quot-erlaubt</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 17:03:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/151866.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 30 Jun 2006 09:07:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 09:07:40 GMT]]></title><description><![CDATA[<p>Hallo,<br />
darf man laut Standard einen Typ, der einen Konstruktor definiert, in einer union verwenden? Hier ein Beispiel:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector3
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
    Vector3() {}
    Vector3(T value) : x(value), y(value), z(value) {}
    Vector3(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

template&lt;typename T&gt;
class Line
{
    union
    {
        struct{ Vector3&lt;T&gt; a, b; };
        struct
        {
            Vector3&lt;T&gt; direction;
            double length;
        };
    };
};

int main()
{
    Line&lt;float&gt; line;
}
</code></pre>
<p>VC++ 8 kompiliert es, aber</p>
<p>g++ schrieb:</p>
<blockquote>
<p>error: member x with constructor not allowed in union</p>
</blockquote>
<ul>
<li>Welcher Compiler verhält sich hier richtig?</li>
<li>Ist diese Einschränkung wirklich so wichtig, oder wäre es nicht wichtiger, wenn der Compiler meckern (zumindest warnen) würde, dass man auf ein Element der union lesend zugreift, obwohl sich der letzte Schreibzugriff auf ein anderes bezog?</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/1088906</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088906</guid><dc:creator><![CDATA[Stan Dart]]></dc:creator><pubDate>Fri, 30 Jun 2006 09:07:40 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 09:12:53 GMT]]></title><description><![CDATA[<p>In dem Fall dürfte der G++ recht haben.</p>
<p>Der Compiler hat keine Ahnung, welche Komponente des union gerade &quot;aktiv&quot; ist (das wäre zu viel Verwaltungsaufwand). Deshalb ist es deine Verantwortung, darüber Buch zu führen. Und deshalb bekommst du undefiniertes Verhalten, wenn du direction/length gefüllt hast und nun versuchen willst, b auszulesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1088909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088909</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Fri, 30 Jun 2006 09:12:53 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 09:19:59 GMT]]></title><description><![CDATA[<p>Hallo,<br />
erstmal unabhängig von deinem Code:<br />
Der Standard verbietet unions mit Membern, die einen selbst-definierten Konstruktor besitzen. Die Antwort auf deine Frage lautet also: nein.</p>
<blockquote>
<p>Ist diese Einschränkung wirklich so wichtig, oder wäre es nicht wichtiger, wenn der Compiler meckern (zumindest warnen) würde, dass man auf ein Element der union lesend zugreift, obwohl sich der letzte Schreibzugriff auf ein anderes bezog?</p>
</blockquote>
<p>Wenn man auf ein Element einer union zugreift, das nicht zuletzt geschrieben wurde, so führt das in der Regel zu undefiniertem Verhalten (es gibt wenige Ausnahmen). D.h. dein Compiler kann dich warnen, er kann aber auch einfach den dritten Weltkrieg auslösen - ohne Vorwarnung.</p>
<p>Jetzt zu deinem Code:<br />
Unions wie diese</p>
<pre><code class="language-cpp">union 
{
        T values[3];
        struct{ T x, y, z; };
};
</code></pre>
<p>sind in C++ nicht erlaubt. Die Zeile struct{ T x, y, z; }; deklariet nichts. Weder einen Typ noch ein Objekt.<br />
Und selbst wenn du einen Typ bzw. ein Objekt deklarieren wollest (struct a{ T x, y, z; };), wäre dies nicht möglich, da dies laut Standard innerhalb einer anonymen union nicht erlaubt ist.</p>
<p>Dein Code ist nicht illegal, weil hier irgendwelche Typen mit Konstruktoren in unions stecken, sondern aus den oben genannten Gründen. Der VC 8 kompiliert das Ganze, weil er eine entsprechende Spracherweiterung besitzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1088915</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088915</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Fri, 30 Jun 2006 09:19:59 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 10:40:48 GMT]]></title><description><![CDATA[<p>Vielen Dank für die Antworten.<br />
Eine Spracherweiterung für anonyme structs in unions scheint der g++ aber auch zu haben. Das folgende Beispiel ist also, sofern ich es richtig verstanden habe, auf doppelte Weise illegal, oder?</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

template&lt;typename T&gt;
class Vector3
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
    Vector3() {}
    Vector3(T value) : x(value), y(value), z(value) {}
    Vector3(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

int main()
{
    Vector3&lt;float&gt; v(.7f, .2f, .5f);
    cout &lt;&lt; &quot;(&quot; &lt;&lt; v.values[0] &lt;&lt; &quot;, &quot; &lt;&lt; v.values[1] &lt;&lt; &quot;, &quot; &lt;&lt; v.values[2] &lt;&lt; &quot;)&quot; &lt;&lt; endl;
    v.values[0] = .1f;
    cout &lt;&lt; v.x &lt;&lt; endl;
    cin.get();
}
</code></pre>
<p>Einmal wegen des anonymen structs, dann wegen des Lesezugriffs auf ein inaktives Element. Das ganze kompiliert sowohl auf VC++ 8 als auch auf MinGW-g++ 3.4.5 wunderbar und verhält sich, wie man es sich wünschen und erwarten würde. Schade, dass g++ keine Spracherweiterung für union-Elemente mit Konstruktoren hat. Der Lesezugriff auf ein inaktives Element ist aber keine Spracherweiterung, sondern eher Mißbrauch fehlender Kontrollfeatures, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1088985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088985</guid><dc:creator><![CDATA[Stan Dart]]></dc:creator><pubDate>Fri, 30 Jun 2006 10:40:48 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 10:50:58 GMT]]></title><description><![CDATA[<p>Stan Dart schrieb:</p>
<blockquote>
<pre><code class="language-cpp">union
    {
        T values[3];
        struct{ T x, y, z; };
    };
</code></pre>
</blockquote>
<p>leidet unter einem anonyme struct. das problem des nicht-trivialen konstruktors oder destruktors entstünde zusätzlich, falls T darüber verfügt.</p>
<pre><code class="language-cpp">union
    {
        struct{ Vector3&lt;T&gt; a, b; };
        struct
        {
            Vector3&lt;T&gt; direction;
            double length;
        };
    };
</code></pre>
<p>hier treten auf jeden fall beide probleme auf. denn vector3&lt;T&gt; hat ja in jedem falle einen nicht-trivialen konstruktor (wobei das trotzdem erst beim instantiieren diagnostiziert werden kann).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1088992</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088992</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 30 Jun 2006 10:50:58 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 10:52:14 GMT]]></title><description><![CDATA[<p>Hallo,<br />
die Spracherweiterung sorgt hier nur dafür, dass die Array-Elemente Namen haben, dass du also statt values[0] einfach x schreiben kannst. Du führst also Alias-Namen ein. Überlagert wird hier nichts. Insofern ist dein Zugriff auch ok. Da die union nur ein einziges echtes Element hat (das Array), kannst du nicht auf ein inaktives Element zugreifen.</p>
<p>Das man in unions keine Typen mit Konstruktoren haben darf hat zum einem mit der Kompatibilität mit C und zum Anderen mit dem &quot;zero cost principle&quot; zu tun. Würden unions solche Typen unterstützen, müsste der Compiler irgendwo Code einschieben, der testet, ob ein Objekt bereits konstruiert wurde oder nicht (selbiges für zerstört), er müsste also verfolgen, welches Element aktiv ist und immer entsprechend reagieren (und zwar in jedem Fall, nicht nur, wenn man verbotener Weise auf ein inaktves Element zugreift).<br />
Verbietet man Typen mit Ctoren ist das alles nicht nötig. Man sagt einfach falscher Zugriff führt zu undefiniertem Verhalten und fertig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1088996</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1088996</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Fri, 30 Jun 2006 10:52:14 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 11:21:54 GMT]]></title><description><![CDATA[<p>Danke.<br />
Bin mal gespannt, ob man im nächsten C++ Standard Typen mit Konstruktoren in unions haben darf. Ich finde, das ist ein cooles Feature vom VC++ Compiler. Solange ein Typ Zugriff auf einen Default-Konstruktor bietet, erlaubt es der VC++ Compiler Objekte dieses Typs in unions verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1089034</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1089034</guid><dc:creator><![CDATA[Stan Dart]]></dc:creator><pubDate>Fri, 30 Jun 2006 11:21:54 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 12:47:55 GMT]]></title><description><![CDATA[<p>Ich habe noch ein bißchen rumgespielt und rausgefunden, dass VC++ Typen mit Konstruktoren in unions nur erlaubt, wenn diese gekapselt sind. Das folgende kompiliert zum Beispiel in VC++ auch nicht:</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector3A
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
	Vector3A() : x(0), y(0), z(0) {}
    Vector3A(T value) : x(value), y(value), z(value) {}
    Vector3A(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

template&lt;typename T&gt;
class Vector3B
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
	Vector3B() : x(1), y(1), z(1) {}
    Vector3B(T value) : x(value), y(value), z(value) {}
    Vector3B(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

class foo
{
public:
    union
    {
		Vector3A&lt;int&gt; va; //das mag der VC++ nicht
		Vector3B&lt;int&gt; vb; //das mag der VC++ nicht
    };
};

int main()
{
   foo f;
}
</code></pre>
<p>Wenn man die Objekte kapselt, kompiliert VC++ das Programm, aber man muss darauf achten, dass die Konstruktion eines Objekts, die Konstruktionen anderer kaputt machen kann:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

template&lt;typename T&gt;
class Vector3A
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
	Vector3A() : x(0), y(0), z(0) {}
    Vector3A(T value) : x(value), y(value), z(value) {}
    Vector3A(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

template&lt;typename T&gt;
class Vector3B
{
public:
    union
    {
        T values[3];
        struct{ T x, y, z; };
    };
	Vector3B() : x(1), y(1), z(1) {}
    Vector3B(T value) : x(value), y(value), z(value) {}
    Vector3B(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {}
};

class foo
{
public:
    union
    {
		struct{Vector3A&lt;int&gt; va;};
		struct{Vector3B&lt;int&gt; vb;};
    };
};

int main()
{
   foo f;
   cout &lt;&lt; f.va.x &lt;&lt; endl; // ACHTUNG! Die Konstruktion von va ist nicht mehr gültig! Wegen der Konstruktion von vb ist va.x 1
   cin.get();
}
</code></pre>
<p>Dieses &quot;Feature&quot; von VC++ ist also mit sehr viel Vorsicht zu genießen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1089090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1089090</guid><dc:creator><![CDATA[Stan Dart]]></dc:creator><pubDate>Fri, 30 Jun 2006 12:47:55 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 20:12:49 GMT]]></title><description><![CDATA[<p>Wieso änderst du nicht die Implementation etwas ab und bietest statt diesem union/struct Wirrwarr zB einen op[] an?</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class Vector3
{
public:
    T x, y, z;
    T&amp; operator [](size_t index)
    {
        return (&amp;x)[index];
    }
};
</code></pre>
<p>Leidet zwar unter den gleichen Alignment Problemen wie deine Version. Lässt sich aber intuitiver benutzen, da du nicht foo.values[...] schreiben musst, sondern foo[..] schreiben kannst. Und ist zudem sprachkonform. Du musst dich also nicht auf irgendwelche Compilererweiterungen verlassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1089288</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1089288</guid><dc:creator><![CDATA[groovemaster]]></dc:creator><pubDate>Fri, 30 Jun 2006 20:12:49 GMT</pubDate></item><item><title><![CDATA[Reply to Ist ein Typ mit Konstruktor in einer &amp;quot;union&amp;quot; erlaubt? on Fri, 30 Jun 2006 21:03:37 GMT]]></title><description><![CDATA[<p>groovemaster schrieb:</p>
<blockquote>
<p>Leidet zwar unter den gleichen Alignment Problemen wie deine Version.</p>
</blockquote>
<p>welche probleme?</p>
<blockquote>
<p>Und ist zudem sprachkonform. Du musst dich also nicht auf irgendwelche Compilererweiterungen verlassen.</p>
</blockquote>
<p>ist das so? ich hatte bisher in diesem forum den eindruck, dass nicht so ganz klar ist, ob und inwieweit eine (POD-)struktur mit membern gleichen typs layoutkompatibel zu einem array mit diesem typ als element ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1089309</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1089309</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 30 Jun 2006 21:03:37 GMT</pubDate></item></channel></rss>