<?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[Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse]]></title><description><![CDATA[<p>Hey...<br />
Ich möchte mehr in Grundlagen verstehen und hab jetzt das probiert:</p>
<pre><code class="language-cpp">union MyUnion
{
	unsigned char b1;
	unsigned char b2;

	unsigned short word;
}; MyUnion globalMyUnion;

struct MyStruct
{
	unsigned short word;
}; MyStruct *pMyStruct;

int main()
{
	// TEST 1 = 33
	globalMyUnion.b1 = 102;
	globalMyUnion.b2 = 33;
	cout &lt;&lt; globalMyUnion.word &lt;&lt; endl;

	// TEST 2 = 52257
	MyUnion myUnion;
	myUnion.b1 = 102;
	myUnion.b2 = 33;
	cout &lt;&lt; myUnion.word &lt;&lt; endl;

	// TEST 3 = 8550
	unsigned char buf[2] = { 102, 33 };
	unsigned char* pBuf = buf;
	pMyStruct = (MyStruct*)pBuf; 
	cout &lt;&lt; pMyStruct-&gt;word &lt;&lt; endl;
}
</code></pre>
<p>Warum sind die Ergebnisse so unterschiedlich? Was passiert bei den einzelnen Tests genau?</p>
<p>Danke!<br />
MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/213563/zwei-char-in-ein-short-quot-schieben-quot-unterschiedliche-ergebnisse</link><generator>RSS for Node</generator><lastBuildDate>Wed, 14 Oct 2026 05:24:07 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/213563.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 19 May 2008 10:44:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 10:44:04 GMT]]></title><description><![CDATA[<p>Hey...<br />
Ich möchte mehr in Grundlagen verstehen und hab jetzt das probiert:</p>
<pre><code class="language-cpp">union MyUnion
{
	unsigned char b1;
	unsigned char b2;

	unsigned short word;
}; MyUnion globalMyUnion;

struct MyStruct
{
	unsigned short word;
}; MyStruct *pMyStruct;

int main()
{
	// TEST 1 = 33
	globalMyUnion.b1 = 102;
	globalMyUnion.b2 = 33;
	cout &lt;&lt; globalMyUnion.word &lt;&lt; endl;

	// TEST 2 = 52257
	MyUnion myUnion;
	myUnion.b1 = 102;
	myUnion.b2 = 33;
	cout &lt;&lt; myUnion.word &lt;&lt; endl;

	// TEST 3 = 8550
	unsigned char buf[2] = { 102, 33 };
	unsigned char* pBuf = buf;
	pMyStruct = (MyStruct*)pBuf; 
	cout &lt;&lt; pMyStruct-&gt;word &lt;&lt; endl;
}
</code></pre>
<p>Warum sind die Ergebnisse so unterschiedlich? Was passiert bei den einzelnen Tests genau?</p>
<p>Danke!<br />
MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512124</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512124</guid><dc:creator><![CDATA[ceplusplus*loggedoff]]></dc:creator><pubDate>Mon, 19 May 2008 10:44:04 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 10:53:05 GMT]]></title><description><![CDATA[<p>Da die Tests 1 und 2 undefiniert sind, lohnt es nicht, über deren Ergebnisse zu spekulieren. Du darfst von einer Union immer nur das jeweils aktuell gültige (sprich, das zuletzt gesetzte) Element ansprechen.</p>
<p>Beim dritten Test kommt ein zu erwartendes Ergebnis raus. Im Speicher liegen die Zahlen (Hex 0x66 und 0x21), welche, da Du vermutlich auf einer Little-Endian Plattform arbeitest, in umgekehrter Reihenfolge interpretiert werden. 0x2166 Hex entspricht 8550.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512132</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512132</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Mon, 19 May 2008 10:53:05 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:08:10 GMT]]></title><description><![CDATA[<p>Die Fälle 2 und 3 sind undefiniert, Fall 1 hat möglicherweise definiertes Verhalten - das muss ich noch mal nachlesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512201</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512201</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 19 May 2008 12:08:10 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:13:49 GMT]]></title><description><![CDATA[<p>Wäre Fall 3 denn definiert, wenn garantiert wäre, dass der Array (für MyStruct) korrekt ausgerichtet ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512207</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512207</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Mon, 19 May 2008 12:13:49 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:20:33 GMT]]></title><description><![CDATA[<p>Es geht mir nämlich darum, die zwei Bytes 102 und 33 auf einen Wert zu bekommen.<br />
Wie soll ich das denn sonst machen?</p>
<p>Danke!<br />
MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512210</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512210</guid><dc:creator><![CDATA[ceplusplus*loggedoff]]></dc:creator><pubDate>Mon, 19 May 2008 12:20:33 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:25:04 GMT]]></title><description><![CDATA[<p>ceplusplus@loggedoff schrieb:</p>
<blockquote>
<p>Es geht mir nämlich darum, die zwei Bytes 102 und 33 auf einen Wert zu bekommen.<br />
Wie soll ich das denn sonst machen?</p>
</blockquote>
<p>Am besten mit legitimen, definierten, plattformunabhängigen Mitteln. <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>
<pre><code class="language-cpp">unsigned char bytes[...];

// extrahiere Bytes 1 und 2, die eine Big-Endian-Repräsentation einer vorzeichenlosen 16-Bit Zahl enthalten
uint16_t word = ( bytes[0] &lt;&lt; 8 ) | bytes[1];
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1512212</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512212</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Mon, 19 May 2008 12:25:04 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:45:13 GMT]]></title><description><![CDATA[<p>Wenn dann müsste die union so aussehen</p>
<pre><code class="language-cpp">union MyUnion
{
    struct tagName { // Name?
    unsigned char b1;
    unsigned char b2;
    } twochar; // Name?

    unsigned short word;
}; MyUnion globalMyUnion;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1512232</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512232</guid><dc:creator><![CDATA[wurst --frickel]]></dc:creator><pubDate>Mon, 19 May 2008 12:45:13 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:53:17 GMT]]></title><description><![CDATA[<p>Aha, danke erstmal.<br />
Hat es etwas mit dem sogenannten &quot;Padding&quot; zu tun, dass Fall 3 undefiniert ist?</p>
<p>Was mache ich aber, wenn ich ein Array hunderter Bytes habe, bestimmte Bytes aber eben zusammengehören also zB. intern einen float repräsentieren und ich eine entsprechende Struktur definieren möchte?</p>
<p>(Ich muss ein unbekanntes Protokoll auswerten)</p>
<p>MfG</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512242</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512242</guid><dc:creator><![CDATA[ceplusplus*loggedoff]]></dc:creator><pubDate>Mon, 19 May 2008 12:53:17 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 12:55:50 GMT]]></title><description><![CDATA[<p>Noch mal nachgelesen. Alle 3 Fälle sind undefiniert, Fall 3 auch unabhäng von Alignmentvoraussetzungen (die kommen noch hinzu). Interessant ist dagegen der Fall, wenn word der erste Member des Unions wäre. Wenn wir annehmen, dass in unserer Implementation Objekt- und Wertrepräsentation von short identisch sind (es existieren also keine Paddingbits oder Traprepräsentationen), dann wäre Fall 1 wohldefiniert (das konkrete Ergebnis aber von der Implementation abhängt), Fall2 unspezifiziert (wegen fehlender Initialisierung) oder wohldefiniert (falls sizeof(char)==sizeof(short) ).</p>
<p>Der Zugriff auf ein Objekt über Ausdrücke mit Zeichentyp ändert nicht den Typ des Objekts, insofern muss die Konkurrenz zur Regel, dass in einem Union nur ein Wert gleichzeitig aktiv sein kann, zuungunsten dieser Regel aufgelöst werden - andernfalls wären elementare Zugriffe etwa per memcpy auf solche Objekte problematisch.</p>
<p>Referenzen (C++): 3.9/2-4;3.10/15;8.5/1;9.5/1</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512246</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512246</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 19 May 2008 12:55:50 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 13:21:22 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Interessant ist dagegen der Fall, wenn word der erste Member des Unions wäre. Wenn wir annehmen, dass in unserer Implementation Objekt- und Wertrepräsentation von short identisch sind (es existieren also keine Paddingbits oder Traprepräsentationen), dann wäre Fall 1 wohldefiniert (das konkrete Ergebnis aber von der Implementation abhängt), Fall2 unspezifiziert (wegen fehlender Initialisierung) oder wohldefiniert (falls sizeof(char)==sizeof(short) ).</p>
</blockquote>
<p>meines wissens nach sind nur zugriffe auf unions wohldefiniert, die einen Wert in der Form auslesen, wie er eingelesen wurde. Sprich, wenn ein word eingelesen wurde, muss ein word ausgelesen werden, nicht ein char oder was auch immer. Das ist ja das große Problem bei unions, dass all diese schönen sachen komplett undefiniert sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512278</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512278</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Mon, 19 May 2008 13:21:22 GMT</pubDate></item><item><title><![CDATA[Reply to Zwei char in ein short &amp;quot;schieben&amp;quot;: Unterschiedliche Ergebnisse on Mon, 19 May 2008 14:17:27 GMT]]></title><description><![CDATA[<p>otze schrieb:</p>
<blockquote>
<p>meines wissens nach sind nur zugriffe auf unions wohldefiniert, die einen Wert in der Form auslesen, wie er eingelesen wurde. Sprich, wenn ein word eingelesen wurde, muss ein word ausgelesen werden, nicht ein char oder was auch immer. Das ist ja das große Problem bei unions, dass all diese schönen sachen komplett undefiniert sind.</p>
</blockquote>
<p>Das steht aber so nirgendwo im Standard und ich denke, man kann es auch nicht durch Auslegung herausbekommen.</p>
<p>ISO 14882:2003 schrieb:</p>
<blockquote>
<p>9.5 Unions [class.union]<br />
1 In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time. [Note: one special guarantee is made in order to simplify the use of unions: If a POD-union contains several POD-structs that share a common initial sequence (9.2), and if an object of this POD-union type contains one of the POD-structs, it is permitted to inspect the common initial sequence of any of POD-struct members; see 9.2. ] The size of a union is sufficient to contain the largest of its data members. Each data member is allocated as if it were the sole member of a struct.</p>
</blockquote>
<p>Dort steht nichts dazu, wie man auf den gespeicherten Wert zugreifen kann (da steht zwar in dem Verweis etwas von &quot;inspect&quot;, nicht aber <em>wie</em> dies zu geschehen hat). Um das herauszufinden, müssen wir an einer ganz anderen Stelle suchen:</p>
<p>ISO 14882:2003 schrieb:</p>
<blockquote>
<p>3.10/15<br />
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 undefined48):<br />
— 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 />
— 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),<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>
</blockquote>
<p>Das ist zunächst einmal eine Regel, die uns sagt, wann etwas <em>nicht</em> definiert ist. Dafür müssen wir wiederum woanders schauen - uns interessieren hier nur char&amp;co., dafür muss man 3.9/4 heranziehen. Betrachten wir das Ganze jetzt aus dem Blickwinkel von union-Membern wird plötzlich klar, warum dort diese merkwürdige Regel des nur-eine-Wert-gleichzeitig-aktiv steht; ohne diese Regel wüssten wir nicht, auf welches Objekt wir 3.10/15 anzuwenden haben. 9.5/1 ist also keine Einschränkung sondern macht das sinnvolle Arbeiten mit Unions überhaupt erst möglich.</p>
<p>Ein bisschen schwieriger ist noch der exotische Fall, falls unser Ausdruck ein rvalue ist. Etwa</p>
<pre><code class="language-cpp">union foo
{
    char i;
    char a[1];
    double d;
};
foo f() { foo x; x.d = 1.0; return x; }
int main()
{
    cout &lt;&lt; f().d; // was nun?
    cout &lt;&lt; f().i; // und hier? im Vergleich zu
    cout &lt;&lt; f().a[0]; // hier?  Dies wäre in C übrigens ill-formed
}
</code></pre>
<p>Uns ist natürlich klar, was bei f().d passiert - es ist aber nicht ganz einfach, dies zu begründen; glücklicherweise sind diese Fälle relativ selten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1512310</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1512310</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 19 May 2008 14:17:27 GMT</pubDate></item></channel></rss>