<?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[Der Teil des Gehirns, der für Byte Order zuständig ist]]></title><description><![CDATA[<p>... scheint vielen Programmierern zu fehlen. Sehr oft stößt man in Code auf die Annahme, dass die Zahldarstellung der CPU irgendwie relevant wäre beim Kodieren von Zahlen. Mich erstaunt das deswegen immer wieder, weil das verlustfreie Aufteilen von Zahlen in kleinere Zahlen so unglaublich einfach ist und trotzdem von erwachsenen Menschen meist nicht richtig verstanden wird. Das Prinzip wird doch schon in der Grundschule unterrichtet. Mehrstellige Zahlen müssen die Schüler dort in Einer, Zehner, Hunderter und Tausender zerlegen. Nichts anderes ist die Zerlegung in Bytes. Und die Byte Order legt einfach fest, ob zuerst die Einer oder zuerst die Tausender (bzw 256er) kommen.</p>
<p>(ein Artikel, der das Problem erklärt: <a href="http://commandcenter.blogspot.de/2012/04/byte-order-fallacy.html" rel="nofollow">The byte order fallacy</a>)</p>
<p>Selbst bei relativ kompetenten Communitys wie Stack Overflow überwiegen <a href="http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c" rel="nofollow">unportable, umständliche Lösungen</a> für dieses Non-Problem.</p>
<p>Eigentlich sollte es nur in seltenen Fällen im Kernel Space als eine der letzten Mikrooptimierungen überhaupt in Frage kommen die Bytes umzudrehen. Keine Ahnung wozu, aber ich kann mir <code>ntohl</code> dort ganz tief unten in einem Treiber vorstellen.</p>
<p>Man kann solche Funktionen in reinem C implementieren ohne etwas über den Prozessor zu wissen. Ganz nebenbei ist das sogar die kürzeste Variante. In C++ ist der Unterschied noch krasser, weil es Funktions-Templates gibt.</p>
<p>Mal ein Code-Beispiel zur Illustration:</p>
<pre><code class="language-cpp">#include &lt;cstdint&gt;
#include &lt;ostream&gt;
#include &lt;stdexcept&gt;
#include &lt;array&gt;
#include &lt;climits&gt;
#include &lt;fstream&gt;

#include &lt;netinet/in.h&gt;

struct Object
{
	std::uint32_t i;
};

template &lt;class Integer&gt;
void encode_big_endian_wrong(std::ostream &amp;out, Integer value)
{
	switch (sizeof(value))
	{
	case 1: break;
	case 2: value = htons(value); break;
	case 4: value = htonl(value); break;
	default: throw std::invalid_argument(&quot;I am too stupid to support arbitrary integer sizes&quot;);
	}
	out.write(reinterpret_cast&lt;char *&gt;(&amp;value), sizeof(value));
}

//value muss unsigned sein, weil bei negativen Werten das Shiften undefiniertes Verhalten hätte.
template &lt;class Unsigned&gt;
typename std::enable_if&lt;std::is_unsigned&lt;Unsigned&gt;::value, void&gt;::type
encode_big_endian_correct_impl(std::ostream &amp;out, Unsigned value)
{
	//Der Puffer soll die Anzahl der Aufrufe von out.write verringern, damit das nicht langsamer
	//wird als die falsche Variante.
	std::array&lt;unsigned char, sizeof(value)&gt; buffer;
	for (std::size_t i = 0; i &lt; buffer.size(); ++i)
	{
		buffer[i] = static_cast&lt;unsigned char&gt;(value &gt;&gt; ((buffer.size() - i - 1) * CHAR_BIT));
	}
	out.write(reinterpret_cast&lt;char *&gt;(buffer.data()), buffer.size());
}

template &lt;class Integer&gt;
void encode_big_endian_correct(std::ostream &amp;out, Integer value)
{
	encode_big_endian_correct_impl(out, static_cast&lt;typename std::make_unsigned&lt;Integer&gt;::type&gt;(value));
}

int main()
{
	std::ofstream file(&quot;out.bin&quot;, std::ios::binary);
	if (!file)
	{
		return 1;
	}
	Object o;
	o.i = 0xAABB;
	encode_big_endian_correct(file, o.i);
	encode_big_endian_wrong(file, o.i);

	//Beide &quot;funktionieren&quot;, aber nur eine Variante
	//ist portabel und funktioniert für alle Integer-Größen.
}
</code></pre>
<p>So ein Funktions-Template gehört, noch etwas verallgemeinert, in Boost und dann in die Standardbibliothek. Davon könnten anscheinend viele profitieren.</p>
<p>EDIT: Interessant ist vielleicht noch der Code, den der Compiler daraus jeweils macht. Die wesentlichen Stellen in GNU AMD64 (erzeugt mit <code>g++ main.cpp -std=c++11 -S -O3</code> ):</p>
<pre><code>; encode_big_endian_correct(file, o.i);
	leaq	16(%rsp), %rsi
	leaq	32(%rsp), %rdi
	movl	$4, %edx
	movb	$0, 16(%rsp)
	movb	$0, 17(%rsp)
	movb	$-86, 18(%rsp)
	movb	$-69, 19(%rsp)
	call	_ZNSo5writeEPKcl
	; encode_big_endian_wrong(file, o.i);
	leaq	12(%rsp), %rsi
	leaq	32(%rsp), %rdi
	movl	$4, %edx
	movl	$-1146486784, 12(%rsp)
	call	_ZNSo5writeEPKcl
</code></pre>
<p>Die unportable Variante mit <code>htonl</code> ist tatsächlich kürzer. GCC bekommt das Loop Unrolling und Inlining zwar hin. Die vier Bytes werden bei der portablen Variante jedoch einzeln gesetzt. Ich bin kein Experte, aber ich halte es für eine triviale Optimierung ein paar <code>mov</code> s zusammenzufügen. Dass das auf <code>-O3</code> nicht gemacht wird, könnte man als Bug bezeichnen.<br />
Der Compiler ist übrigens <code>g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3</code> .<br />
Ich würde trotzdem die portable Variante nehmen, weil es bei IO nicht auf die paar CPU-Takte ankommt. Zudem ist es wahrscheinlich, dass zukünftige Compiler hier besser optimieren werden. Clang 3.2 erzeugt mit den gleichen Optionen wie GCC bei beiden Varianten bereits den gleichen Code.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/319734/der-teil-des-gehirns-der-für-byte-order-zuständig-ist</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Jul 2026 22:14:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/319734.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 30 Aug 2013 20:42:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Fri, 30 Aug 2013 22:44:56 GMT]]></title><description><![CDATA[<p>... scheint vielen Programmierern zu fehlen. Sehr oft stößt man in Code auf die Annahme, dass die Zahldarstellung der CPU irgendwie relevant wäre beim Kodieren von Zahlen. Mich erstaunt das deswegen immer wieder, weil das verlustfreie Aufteilen von Zahlen in kleinere Zahlen so unglaublich einfach ist und trotzdem von erwachsenen Menschen meist nicht richtig verstanden wird. Das Prinzip wird doch schon in der Grundschule unterrichtet. Mehrstellige Zahlen müssen die Schüler dort in Einer, Zehner, Hunderter und Tausender zerlegen. Nichts anderes ist die Zerlegung in Bytes. Und die Byte Order legt einfach fest, ob zuerst die Einer oder zuerst die Tausender (bzw 256er) kommen.</p>
<p>(ein Artikel, der das Problem erklärt: <a href="http://commandcenter.blogspot.de/2012/04/byte-order-fallacy.html" rel="nofollow">The byte order fallacy</a>)</p>
<p>Selbst bei relativ kompetenten Communitys wie Stack Overflow überwiegen <a href="http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c" rel="nofollow">unportable, umständliche Lösungen</a> für dieses Non-Problem.</p>
<p>Eigentlich sollte es nur in seltenen Fällen im Kernel Space als eine der letzten Mikrooptimierungen überhaupt in Frage kommen die Bytes umzudrehen. Keine Ahnung wozu, aber ich kann mir <code>ntohl</code> dort ganz tief unten in einem Treiber vorstellen.</p>
<p>Man kann solche Funktionen in reinem C implementieren ohne etwas über den Prozessor zu wissen. Ganz nebenbei ist das sogar die kürzeste Variante. In C++ ist der Unterschied noch krasser, weil es Funktions-Templates gibt.</p>
<p>Mal ein Code-Beispiel zur Illustration:</p>
<pre><code class="language-cpp">#include &lt;cstdint&gt;
#include &lt;ostream&gt;
#include &lt;stdexcept&gt;
#include &lt;array&gt;
#include &lt;climits&gt;
#include &lt;fstream&gt;

#include &lt;netinet/in.h&gt;

struct Object
{
	std::uint32_t i;
};

template &lt;class Integer&gt;
void encode_big_endian_wrong(std::ostream &amp;out, Integer value)
{
	switch (sizeof(value))
	{
	case 1: break;
	case 2: value = htons(value); break;
	case 4: value = htonl(value); break;
	default: throw std::invalid_argument(&quot;I am too stupid to support arbitrary integer sizes&quot;);
	}
	out.write(reinterpret_cast&lt;char *&gt;(&amp;value), sizeof(value));
}

//value muss unsigned sein, weil bei negativen Werten das Shiften undefiniertes Verhalten hätte.
template &lt;class Unsigned&gt;
typename std::enable_if&lt;std::is_unsigned&lt;Unsigned&gt;::value, void&gt;::type
encode_big_endian_correct_impl(std::ostream &amp;out, Unsigned value)
{
	//Der Puffer soll die Anzahl der Aufrufe von out.write verringern, damit das nicht langsamer
	//wird als die falsche Variante.
	std::array&lt;unsigned char, sizeof(value)&gt; buffer;
	for (std::size_t i = 0; i &lt; buffer.size(); ++i)
	{
		buffer[i] = static_cast&lt;unsigned char&gt;(value &gt;&gt; ((buffer.size() - i - 1) * CHAR_BIT));
	}
	out.write(reinterpret_cast&lt;char *&gt;(buffer.data()), buffer.size());
}

template &lt;class Integer&gt;
void encode_big_endian_correct(std::ostream &amp;out, Integer value)
{
	encode_big_endian_correct_impl(out, static_cast&lt;typename std::make_unsigned&lt;Integer&gt;::type&gt;(value));
}

int main()
{
	std::ofstream file(&quot;out.bin&quot;, std::ios::binary);
	if (!file)
	{
		return 1;
	}
	Object o;
	o.i = 0xAABB;
	encode_big_endian_correct(file, o.i);
	encode_big_endian_wrong(file, o.i);

	//Beide &quot;funktionieren&quot;, aber nur eine Variante
	//ist portabel und funktioniert für alle Integer-Größen.
}
</code></pre>
<p>So ein Funktions-Template gehört, noch etwas verallgemeinert, in Boost und dann in die Standardbibliothek. Davon könnten anscheinend viele profitieren.</p>
<p>EDIT: Interessant ist vielleicht noch der Code, den der Compiler daraus jeweils macht. Die wesentlichen Stellen in GNU AMD64 (erzeugt mit <code>g++ main.cpp -std=c++11 -S -O3</code> ):</p>
<pre><code>; encode_big_endian_correct(file, o.i);
	leaq	16(%rsp), %rsi
	leaq	32(%rsp), %rdi
	movl	$4, %edx
	movb	$0, 16(%rsp)
	movb	$0, 17(%rsp)
	movb	$-86, 18(%rsp)
	movb	$-69, 19(%rsp)
	call	_ZNSo5writeEPKcl
	; encode_big_endian_wrong(file, o.i);
	leaq	12(%rsp), %rsi
	leaq	32(%rsp), %rdi
	movl	$4, %edx
	movl	$-1146486784, 12(%rsp)
	call	_ZNSo5writeEPKcl
</code></pre>
<p>Die unportable Variante mit <code>htonl</code> ist tatsächlich kürzer. GCC bekommt das Loop Unrolling und Inlining zwar hin. Die vier Bytes werden bei der portablen Variante jedoch einzeln gesetzt. Ich bin kein Experte, aber ich halte es für eine triviale Optimierung ein paar <code>mov</code> s zusammenzufügen. Dass das auf <code>-O3</code> nicht gemacht wird, könnte man als Bug bezeichnen.<br />
Der Compiler ist übrigens <code>g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3</code> .<br />
Ich würde trotzdem die portable Variante nehmen, weil es bei IO nicht auf die paar CPU-Takte ankommt. Zudem ist es wahrscheinlich, dass zukünftige Compiler hier besser optimieren werden. Clang 3.2 erzeugt mit den gleichen Optionen wie GCC bei beiden Varianten bereits den gleichen Code.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349468</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349468</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 30 Aug 2013 22:44:56 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Fri, 30 Aug 2013 21:18:23 GMT]]></title><description><![CDATA[<p>Das erzeugt allerdings deutlich langsameren Code als Shifts für 32-bit. Und dann gibt's da ja auch noch <a href="http://en.wikipedia.org/wiki/X86_instruction_listings" rel="nofollow">bswap</a>.<br />
Siehe auch <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3620.pdf" rel="nofollow">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3620.pdf</a><br />
und <a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/swap/std-proposals/9wioV_jxuZs/itFbN0_9LrcJ" rel="nofollow">https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/swap/std-proposals/9wioV_jxuZs/itFbN0_9LrcJ</a><br />
und (hat sich nichts geändert) <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3646.pdf" rel="nofollow">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3646.pdf</a></p>
<p>Edit: Jetzt hast du den generierten Code eineditiert.</p>
<blockquote>
<p>Ich würde trotzdem die portable Variante nehmen, weil es bei IO nicht auf die paar CPU-Takte ankommt.</p>
</blockquote>
<p>Bei Netzwerk-Kram vermutlich nicht, aber bei anderen Dingen (z.B. Verschlüsselung/Hashing) kann das schon einen Unterschied machen. Wenn Clang allerdings überall das gleiche generiert, zeigt das zumindest die Richtung an. Aber wie sieht's eigentlich mit std::reverse aus? <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/2349469</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349469</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Fri, 30 Aug 2013 21:18:23 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Fri, 30 Aug 2013 21:51:14 GMT]]></title><description><![CDATA[<p>Wenn man mit htons, htonl usw. nutzt, kann man damit dann auch ein unsigned long übers Netzwerk schicken und es wird garantiert korrekt ankommen?</p>
<p>Vorausgesetzt die Gegenseite ruft ntohs und nthol auf?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349476</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349476</guid><dc:creator><![CDATA[gfhffgh]]></dc:creator><pubDate>Fri, 30 Aug 2013 21:51:14 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Fri, 30 Aug 2013 22:42:36 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Das erzeugt allerdings deutlich langsameren Code als Shifts für 32-bit.</p>
</blockquote>
<p>Meinst du x86? Warum sollte da etwas anderes generiert werden?</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Und dann gibt's da ja auch noch <a href="http://en.wikipedia.org/wiki/X86_instruction_listings" rel="nofollow">bswap</a>.<br />
Siehe auch <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3620.pdf" rel="nofollow">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3620.pdf</a><br />
und <a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/swap/std-proposals/9wioV_jxuZs/itFbN0_9LrcJ" rel="nofollow">https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/swap/std-proposals/9wioV_jxuZs/itFbN0_9LrcJ</a><br />
und (hat sich nichts geändert) <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3646.pdf" rel="nofollow">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3646.pdf</a></p>
</blockquote>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Aber wie sieht's eigentlich mit std::reverse aus? <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>
</blockquote>
<p>Ich will gar keine Bytes tauschen. Niemand sollte das wollen, darum geht es hier doch.</p>
<p>gfhffgh schrieb:</p>
<blockquote>
<p>Wenn man mit htons, htonl usw. nutzt, kann man damit dann auch ein unsigned long übers Netzwerk schicken und es wird garantiert korrekt ankommen?</p>
<p>Vorausgesetzt die Gegenseite ruft ntohs und nthol auf?</p>
</blockquote>
<p>Nö, aber mit meiner portablen Lösung geht das problemlos.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349479</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349479</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Fri, 30 Aug 2013 22:42:36 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 01:16:27 GMT]]></title><description><![CDATA[<p>1.) Was zur Hoelle ist dein Problem?<br />
2.) Deine &quot;korrekte&quot; Loesung ist kacke. Kann man auch ohne Template machen, wenn gleich ein (unsigned) char* akzeptiert wird.<br />
3.) Und wenn schon Templates, dann mit Spezialisierung fuer die einzelnen Typen.<br />
4.) Dein Code ist nicht performant, da zu viele Speicherzugriffe. Arbeiten auf Registern ist erwuenscht.<br />
5.) Keine Begruendung fuer &quot;unportabel&quot; geliefert.</p>
<blockquote>
<p>Ich will gar keine Bytes tauschen. Niemand sollte das wollen, darum geht es hier doch.</p>
</blockquote>
<p>Ach, und was machst du dann?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349485</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349485</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sat, 31 Aug 2013 01:16:27 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 05:58:51 GMT]]></title><description><![CDATA[<p>1.) hat er geschrieben<br />
2.) Das ist hässlich.<br />
3.) Warum?<br />
4.) Clang erzeugt den gleichen Code in beiden Varianten. Praxis schlägt Theorie.<br />
5.) htonl gibts nicht im Standard.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349497</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Sat, 31 Aug 2013 05:58:51 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 06:12:17 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Sehr oft stößt man in Code auf die Annahme, dass die Zahldarstellung der CPU irgendwie relevant wäre beim Kodieren von Zahlen.</p>
</blockquote>
<p>Sehr oft ist sie auch richtig, weil fast keiner für mehrere (Betriebs)systeme programmiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349498</guid><dc:creator><![CDATA[Tja]]></dc:creator><pubDate>Sat, 31 Aug 2013 06:12:17 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 13:50:04 GMT]]></title><description><![CDATA[<p>Zunächst mal ist die Berechnung der &quot;falschen&quot; Funktion aus deinem Assembly komplett wegoptimiert. Du wirst feststellen, dass</p>
<pre><code>movl    $-1146486784, 12(%rsp)
</code></pre>
<p>schlicht den bereits vorgeswappten Wert ins Register schiebt, bevor write aufgerufen wird (-1146486784 == 0xbbaa0000).</p>
<p>Ersetz mal</p>
<pre><code class="language-cpp">o.i = 0xAABB;
</code></pre>
<p>durch</p>
<pre><code class="language-cpp">#include &lt;ctime&gt;
#include &lt;cstdlib&gt;

...

std::srand(std::time(0));
o.i = std::rand();
</code></pre>
<p>und schau nochmal, was der Compiler ausspuckt. Relevanter Teil:</p>
<pre><code>bswap   %ebx
</code></pre>
<p>...und jeder Code, der da auf nem x86 was anderes erzeugt, gehört von vorneherein in die Tonne.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349543</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349543</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Sat, 31 Aug 2013 13:50:04 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 18:21:59 GMT]]></title><description><![CDATA[<p>Ich bleib bei reinterpret_cast fuer Serialisierung, danke trotzdem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349566</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349566</guid><dc:creator><![CDATA[Kellerautomat]]></dc:creator><pubDate>Sat, 31 Aug 2013 18:21:59 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sat, 31 Aug 2013 23:19:43 GMT]]></title><description><![CDATA[<p>Tja schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Sehr oft stößt man in Code auf die Annahme, dass die Zahldarstellung der CPU irgendwie relevant wäre beim Kodieren von Zahlen.</p>
</blockquote>
<p>Sehr oft ist sie auch richtig, weil fast keiner für mehrere (Betriebs)systeme programmiert.</p>
</blockquote>
<p>Was die Annahme nicht richtiger macht bzw. völlig orthogonal dazu ist. Aber unabhängig davon: du schreibst also nur Wegwerfprogramme?</p>
<p>Guck dich doch mal um wieviel Code, der vor vielen Jahren geschrieben wurde, heute noch im Einsatz ist. Die verwendete Hardware und die verwendeten Systeme haben sich (zum Teil massiv) verändert, aber der Code läuft immer noch.</p>
<p>Selbst wenn du heute nur x86-Maschinen einsetzt, kann sich die Welt ganz schnell verändern. Ist es denn so undenkbar, dass dein Code plötzlich auf einer ganz anderen Geräteklasse laufen könnte, z.B. weil die verfügbare Rechenleistung sich dort stark erhöht hat?</p>
<p>Siehe Embedded-Systeme in den letzten Jahren. Dort läuft heute oft Code, der vor einiger Zeit noch großen Timesharing-Systemen und später den Workstations/PCs vorbehalten war.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349580</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349580</guid><dc:creator><![CDATA[badgerbadgerbadger]]></dc:creator><pubDate>Sat, 31 Aug 2013 23:19:43 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 01:18:33 GMT]]></title><description><![CDATA[<blockquote>
<p>1.) hat er geschrieben</p>
</blockquote>
<p>Und ich verstehe es nicht, was problematisch sein soll.</p>
<blockquote>
<p>2.) Das ist hässlich.</p>
</blockquote>
<p>Die for-Schleife und Speicherzugriffe sind haesslich, weil unnoetig.</p>
<blockquote>
<p>3.) Warum?</p>
</blockquote>
<p>Damit man bswap16, bswap32 und bswap64 oder aehnliches einsetzen kann. Damit es eben nur fuer primitive Typen definiert ist und nicht fuer jede Klasse. Damit die Operation fuer Integer mit mehr Bit auf den mit weniger Bit aufbauen kann.</p>
<blockquote>
<p>4.) Clang erzeugt den gleichen Code in beiden Varianten. Praxis schlägt Theorie.</p>
</blockquote>
<p>Der Bockmist wurde schon geklaert.</p>
<blockquote>
<p>5.) htonl gibts nicht im Standard.</p>
</blockquote>
<p>Nicht alles triviale muss im Standard sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349585</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349585</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Sun, 01 Sep 2013 01:18:33 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 08:59:21 GMT]]></title><description><![CDATA[<p>Noch als Anmerkung: Der &quot;korrekte&quot; Code funktioniert nur auf Little-Endian-Maschinen, ist also alles andere als portabel. Auf Big-Endian-Maschinen müssen ntohl etc. nichts machen. Mixed-Endian ist etwas aus der Mode gekommen, aber damit klappt das natürlich auch nicht. Ich glaube, es gibt auf ARM einen corner case mit packed structs, wo einem mixed-endian passieren kann, müsste das aber nachprüfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349613</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349613</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Sun, 01 Sep 2013 08:59:21 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 09:01:49 GMT]]></title><description><![CDATA[<p>Ah, ich nehme das zurück. Habe mich da verlesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349615</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349615</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Sun, 01 Sep 2013 09:01:49 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 13:50:10 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Meinst du x86? Warum sollte da etwas anderes generiert werden?</p>
</blockquote>
<p>Wegen bswap, und sogar shifts wären schneller.</p>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Ich will gar keine Bytes tauschen. Niemand sollte das wollen, darum geht es hier doch.</p>
</blockquote>
<p>Versteh ich nicht.. macht encode_big_endian_correct_impl nicht genau das, bytes tauschen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349680</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sun, 01 Sep 2013 13:50:10 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 14:37:23 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<pre><code class="language-cpp">//value muss unsigned sein, weil bei negativen Werten das Shiften undefiniertes Verhalten hätte.
template &lt;class Unsigned&gt;
typename std::enable_if&lt;std::is_unsigned&lt;Unsigned&gt;::value, void&gt;::type
encode_big_endian_correct_impl(std::ostream &amp;out, Unsigned value)
{
	//Der Puffer soll die Anzahl der Aufrufe von out.write verringern, damit das nicht langsamer
	//wird als die falsche Variante.
	std::array&lt;unsigned char, sizeof(value)&gt; buffer;
	for (std::size_t i = 0; i &lt; buffer.size(); ++i)
	{
		buffer[i] = static_cast&lt;unsigned char&gt;(value &gt;&gt; ((buffer.size() - i - 1) * CHAR_BIT));
	}
	out.write(reinterpret_cast&lt;char *&gt;(buffer.data()), buffer.size());
}

template &lt;class Integer&gt;
void encode_big_endian_correct(std::ostream &amp;out, Integer value)
{
	encode_big_endian_correct_impl(out, static_cast&lt;typename std::make_unsigned&lt;Integer&gt;::type&gt;(value));
}
</code></pre>
</blockquote>
<p>Wenn du schon das Maul so weit aufreisst, dann schreibe doch bitte richtigen Code. Deiner ist nämlich falsch.<br />
1. Funktioniert nicht mit bool<br />
2. Strict Aliasing wird verletzt, UB</p>
<pre><code class="language-cpp">template &lt;class Integer,
          typename = typename std::enable_if&lt;std::is_integral&lt;Integer&gt;::value&gt;::type&gt;
Integer hton2(Integer value)
{
  using unsigned_integer = typename std::make_unsigned&lt;Integer&gt;::type;
  unsigned_integer x(value);
  static_assert(CHAR_BIT == 8, &quot;I'm too stupid, please use htons&quot;);
  unsigned char arr[sizeof(x)];
  for (std::size_t i=0; i&lt;sizeof(x); ++i)
    arr[i] = (value&gt;&gt;(8*(sizeof(x) - 1 - i)))&amp;0xFF;
  std::memcpy(static_cast&lt;void*&gt;(&amp;x), arr, sizeof(x));
  return x;
}
char hton2(bool value) { return hton2(static_cast&lt;char&gt;(value)); }

template &lt;class Integer&gt;
void encode_big_endian_correct(std::ostream &amp;out, Integer value)
{
  out.write(hton2(value), sizeof(value));
}
</code></pre>
<p>Was war nochmal dein Argument? hton sei unnötig!?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349684</guid><dc:creator><![CDATA[punner]]></dc:creator><pubDate>Sun, 01 Sep 2013 14:37:23 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Sun, 01 Sep 2013 14:42:53 GMT]]></title><description><![CDATA[<p>punner schrieb:</p>
<blockquote>
<p>2. Strict Aliasing wird verletzt, UB</p>
</blockquote>
<p>Nö. Lies 3.10/10 noch mal genau.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349685</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349685</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Sun, 01 Sep 2013 14:42:53 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 17:59:52 GMT]]></title><description><![CDATA[<p>Ich habe das noch einmal für Werte aus <code>std::rand</code> gemacht. Zu meiner Überraschung können Compiler das nicht optimieren. Weder GCC noch Clang erkennt das Muster und generiert <code>bswap</code> . <code>htonl</code> wird aber durch <code>bswap</code> ersetzt.</p>
<p>Clang 3.2 generiert folgendes:</p>
<pre><code>calll	rand
	movl	%eax, %ebx

	shrl	$24, %eax
	movb	%al, 296(%esp)
	movl	%ebx, %eax
	shrl	$16, %eax
	movb	%al, 297(%esp)
	movb	%bh, 298(%esp)
	movb	%bl, 299(%esp)
	leal	296(%esp), %eax
	movl	%eax, 4(%esp)
	movl	%edi, (%esp)
	movl	$4, 8(%esp)
	calll	_ZNSo5writeEPKci

	bswapl	%ebx
	movl	%ebx, 300(%esp)
	leal	300(%esp), %eax
	movl	%eax, 4(%esp)
	movl	%edi, (%esp)
	movl	$4, 8(%esp)
	calll	_ZNSo5writeEPKci
</code></pre>
<p>Wieder etwas gelernt. Hier sollte man dem Compiler dabei helfen optimalen Code zu generieren. Wenn <code>htonl</code> zur Verfügung steht, kann man es benutzen, um Premature Pessimization zu vermeiden. Die Variante mit der Schleife kann dann als Fallback dienen und kommt bei <code>long long</code> zum Einsatz. Wenn man ganz sicher weiß, dass die native Byte Order Big Endian ist, kann man die Schleife weglassen, um den Compiler nicht zu verwirren.</p>
<pre><code class="language-cpp">#include &lt;cstdint&gt;
#include &lt;ostream&gt;
#include &lt;climits&gt;
#include &lt;fstream&gt;
#include &lt;cstdlib&gt;

#define BIG_ENDIAN_HOST_DETECTED 0

#define HTONL_DETECTED 1
#include &lt;netinet/in.h&gt;

template &lt;class T&gt;
struct is_non_bool_integral : std::is_integral&lt;T&gt;
{
};

template &lt;&gt;
struct is_non_bool_integral&lt;bool&gt; : std::false_type
{
};

template &lt;class Integer&gt;
typename std::enable_if&lt;is_non_bool_integral&lt;typename std::decay&lt;Integer&gt;::type&gt;::value, void&gt;::type
encode_big_endian_compromise(std::ostream &amp;out, Integer value)
{
	Integer buffer;
	switch (sizeof(value))
	{
#if HTONL_DETECTED
	case 2:
		buffer = htons(value);
		break;

	case 4:
		buffer = htonl(value);
		break;
#endif

	default:
		{
#if !BIG_ENDIAN_HOST_DETECTED
			typedef typename std::make_unsigned&lt;Integer&gt;::type Unsigned;
			Unsigned const shiftableValue = value;
			unsigned char * const digits = reinterpret_cast&lt;unsigned char *&gt;(&amp;buffer);
			for (std::size_t i = 0; i &lt; sizeof(buffer); ++i)
			{
				digits[i] = static_cast&lt;unsigned char&gt;(
				             shiftableValue &gt;&gt; ((sizeof(buffer) - i - 1) * CHAR_BIT)
				            );
			}
#endif
			break;
		}
	}
	out.write(reinterpret_cast&lt;char *&gt;(&amp;buffer), sizeof(buffer));
}

int main()
{
	std::ofstream file(&quot;out.bin&quot;, std::ios::binary);
	if (!file)
	{
		return 1;
	}
	std::uint32_t const i = std::rand();
	encode_big_endian_compromise(file, i);
}
</code></pre>
<p>punner schrieb:</p>
<blockquote>
<p>1. Funktioniert nicht mit bool</p>
</blockquote>
<p>Soll es auch nicht.</p>
<p>Danke für die Antworten, die konstruktiv sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349927</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349927</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Sep 2013 17:59:52 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 20:48:29 GMT]]></title><description><![CDATA[<blockquote>
<p>Danke für die Antworten, die konstruktiv sind.</p>
</blockquote>
<p>Danke, dass du auf Kritikpunkte nicht eingegangen bist. Danke, dass dein Code noch komplexer geworden ist. Danke, fuer eine inperformante Loesung eines gut untersuchten und mittlerweile voellig trivialen Problems. Danke, dass es an streams gekoppelt ist. Danke, dass es nicht fuer Arrays funktioniert. Danke fuer all die Template-Magic und die Makros. Danke dafuer, dass du dir keine Anregungen <code>long long</code> z.B. <a href="http://repo-genesis3.cbi.utsa.edu/crossref/ns-sli/usr/include/bits/byteswap.h.html" rel="nofollow">hier</a> geholt hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349944</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349944</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 02 Sep 2013 20:48:29 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 21:21:32 GMT]]></title><description><![CDATA[<p>kann jemand Zeile 120-133 Standardkonform und portabel aufschreiben? <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="🙂"
    /> Dann hat ja knivil recht und der Thread kann geschlossen werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349948</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349948</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Mon, 02 Sep 2013 21:21:32 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 21:31:47 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>TyRoXx schrieb:</p>
<blockquote>
<p>Ich will gar keine Bytes tauschen. Niemand sollte das wollen, darum geht es hier doch.</p>
</blockquote>
<p>Versteh ich nicht.. macht encode_big_endian_correct_impl nicht genau das, bytes tauschen?</p>
</blockquote>
<p>Nein, dann würde das Template <code>swap</code> oder so im Namen haben. Es soll nur Zahlen kodieren (High Level) und die konkrete Implementation auf der Plattform interessiert nicht (Low Level). Auf einer Big-Endian-Plattform würde nicht einmal etwas vertauscht werden.</p>
<p>Die &quot;falsche&quot; Variante besteht aus zwei Schritten: Zahl vorbereiten ( <code>htonl</code> ), vorbereitete Zahl als POD wegschreiben. (Im ersten Beispiel-Code habe ich die zwei Schritte zusammengefasst, aber typischerweise machen die Leute nicht einmal das.)<br />
Die &quot;richtige&quot; ist nur ein Schritt: Zahl im richtigen Format wegschreiben.</p>
<p>Ob die zweite Variante mit <code>htonl</code> implementiert ist, interessiert dabei nicht. Die Kodierung ist genau ein mal in einem Header implementiert und kann idiotensicher benutzt werden. Der Anwender kommt nicht mit plattformabhängigen Funktionen wie <code>htons</code> in Berührung. Er profitiert aber trotzdem von den Optimierungen.</p>
<p>knivil schrieb:</p>
<blockquote>
<p>Danke, dass du auf Kritikpunkte nicht eingegangen bist.</p>
</blockquote>
<p>Worauf soll ich denn noch eingehen?</p>
<p>knivil schrieb:</p>
<blockquote>
<p>Danke, dass dein Code noch komplexer geworden ist. [...]Danke, dass es an streams gekoppelt ist. Danke, dass es nicht fuer Arrays funktioniert. Danke fuer all die Template-Magic und die Makros.</p>
</blockquote>
<p>Tut mir leid, dass du nicht mehr mitkommst. Irgendwo im Forum gibt es einen Thread mit guten Büchern über C++.</p>
<p>knivil schrieb:</p>
<blockquote>
<p>Danke, fuer eine inperformante Loesung eines gut untersuchten und mittlerweile voellig trivialen Problems.</p>
</blockquote>
<p>Hast du eigentlich mein letztes Programm verstanden? Was soll da noch performanter gehen, ich verwende doch schon <code>htonl</code> . Ich habe gemerkt, dass Compiler damit besser arbeiten können und meinen Code entsprechend angepasst.</p>
<p>knivil schrieb:</p>
<blockquote>
<p>Danke dafuer, dass du dir keine Anregungen <code>long long</code> z.B. <a href="http://repo-genesis3.cbi.utsa.edu/crossref/ns-sli/usr/include/bits/byteswap.h.html" rel="nofollow">hier</a> geholt hast.</p>
</blockquote>
<p>Intrinsics für <code>long long</code> . Wow, High Tech. Das wäre jetzt voll wichtig gewesen für meine Argumentation. Reicht ja nicht, dass mein Programm schon für 16 und 32 Bit optimal ist und nur zur Demonstration des Prinzips dienen soll.</p>
<p>otze schrieb:</p>
<blockquote>
<p>kann jemand Zeile 120-133 Standardkonform und portabel aufschreiben? <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="🙂"
    /> Dann hat ja knivil recht und der Thread kann geschlossen werden.</p>
</blockquote>
<p>Genau, schließt alle interessanten Diskussionen!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349949</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349949</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Sep 2013 21:31:47 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 21:34:54 GMT]]></title><description><![CDATA[<p>1.) Der union-Trick funktioniert auf allen mir bekannten Compilern/Architekturen (zugegeben, sind nicht viel). Vielleicht sollte der Standard diesbezueglich nachgeruestet werden.<br />
2.) Zeile 100-108 sieht auch gut aus. Man kann gern noch etwas make unsigned rumspielen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349951</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349951</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 02 Sep 2013 21:34:54 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 21:41:24 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>1.) Der union-Trick funktioniert auf allen mir bekannten Compilern/Architekturen (zugegeben, sind nicht viel). Vielleicht sollte der Standard diesbezueglich nachgeruestet werden.</p>
</blockquote>
<p>Ohh, you think darkness is your ally. ~</p>
<p>knivil schrieb:</p>
<blockquote>
<p>Man kann gern noch etwas make unsigned rumspielen.</p>
</blockquote>
<p>Das ist nicht &quot;rumspielen&quot;, sondern es gibt dem Shift definiertes Verhalten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349953</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349953</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Sep 2013 21:41:24 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 21:54:13 GMT]]></title><description><![CDATA[<p>TyRoXx schrieb:</p>
<blockquote>
<p>Das ist nicht &quot;rumspielen&quot;, sondern es gibt dem Shift definiertes Verhalten.</p>
</blockquote>
<p>Genau das meine ich. Du gehst nicht auf das eigentliche Problem ein. Ich weiss das shift nur fuer unsigned definiert ist. Aber: Was ist an Zeile 100-108 jetzt schlecht, bis auf das unsigned oder Macros?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349955</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 02 Sep 2013 21:54:13 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 22:01:10 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Was ist an Zeile 100-108 jetzt schlecht, bis auf das unsigned oder Macros?</p>
</blockquote>
<p>Zeile 100-108 von <a href="http://repo-genesis3.cbi.utsa.edu/crossref/ns-sli/usr/include/bits/byteswap.h.html" rel="nofollow">http://repo-genesis3.cbi.utsa.edu/crossref/ns-sli/usr/include/bits/byteswap.h.html</a>:</p>
<pre><code class="language-cpp"># define __bswap_constant_64(x) \
      ((((x) &amp; 0xff00000000000000ull) &gt;&gt; 56)                                   \
       | (((x) &amp; 0x00ff000000000000ull) &gt;&gt; 40)                                 \
       | (((x) &amp; 0x0000ff0000000000ull) &gt;&gt; 24)                                 \
       | (((x) &amp; 0x000000ff00000000ull) &gt;&gt; 8)                                  \
       | (((x) &amp; 0x00000000ff000000ull) &lt;&lt; 8)                                  \
       | (((x) &amp; 0x0000000000ff0000ull) &lt;&lt; 24)                                 \
       | (((x) &amp; 0x000000000000ff00ull) &lt;&lt; 40)                                 \
       | (((x) &amp; 0x00000000000000ffull) &lt;&lt; 56))
</code></pre>
<p>Meinst du das ernst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349958</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349958</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 02 Sep 2013 22:01:10 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 22:04:58 GMT]]></title><description><![CDATA[<p>Oh, wir spielen uns also mit Pseudofragen zu, damit wir uns dann nachher gegenseitig auslachen koennen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349959</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349959</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 02 Sep 2013 22:04:58 GMT</pubDate></item><item><title><![CDATA[Reply to Der Teil des Gehirns, der für Byte Order zuständig ist on Mon, 02 Sep 2013 22:05:50 GMT]]></title><description><![CDATA[<p>Ich verstehe nicht, welches Problem in diesem Thread gelöst werden soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2349960</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2349960</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Mon, 02 Sep 2013 22:05:50 GMT</pubDate></item></channel></rss>