text: c++ — Endianness programmgesteuert in einem C++ - Programm erkennen
  /Endianness programmgesteuert in einem C++ - Programm erkennen
  Gibt es eine programmatische Methode, um zu ermitteln, ob Sie sich in einer Big-Endian- oder Little-Endian-Architektur befinden oder nicht? Ich muss in der Lage sein, Code zu schreiben, der auf einem Intel- oder PPC -System ausgeführt wird und genau denselben Code verwendet (d. H. Keine bedingte Kompilierung).
  16.06.2009 Jay T
  Ich mag die Methode nicht, die auf dem Typ Punning basiert - sie wird oft vom Compiler gewarnt. Genau dafür sind Gewerkschaften da!
  Das Prinzip ist dem von anderen vorgeschlagenen Typfall gleichwertig, aber das ist klarer - und gemäß C99 ist es garantiert korrekt. gcc bevorzugt dies gegenüber der direkten Zeigerumwandlung.
  Dies ist auch viel besser als die Festlegung des Endianness zur Kompilierzeit. Für Betriebssysteme, die Multi-Architekturen unterstützen (z. B. fette Binärdateien unter Mac OS X), wird dies für beide Seiten von ppc/i386 funktionieren, während es sonst sehr leicht ist, die Dinge ansonsten durcheinander zu bringen .
  16.06.2009 David Cournapeau
  Sie können dies tun, indem Sie ein int setzen und Bits ausmaskieren. Die einfachste Möglichkeit ist jedoch, die eingebauten Netzwerkbyteumwandlungsoperationen zu verwenden (da die Netzwerkbyteordnung immer big endian ist).
  Ein bisschen Fummeln könnte schneller sein, aber dieser Weg ist einfach, unkompliziert und ziemlich unmöglich zu vermasseln.
  16.06.2009 Eric Petroelje
  Bitte sehen Sie diesen Artikel :
  Hier ist etwas Code, um zu bestimmen, was .__ ist. der Typ Ihrer Maschine
  16.06.2009 Andrew Hare
  Dies geschieht normalerweise zur Kompilierzeit (besonders aus Performance-Gründen), indem die im Compiler verfügbaren Header-Dateien verwendet oder eigene erstellt werden. Unter Linux haben Sie die Header-Datei "/usr/include/endian.h"
  16.06.2009 bill
  Sie können std::endian verwenden, wenn Sie Zugriff auf C++ 20-Compiler wie GCC 8+ oder Clang 7+ haben:
  01.07.2016 Lyberta
  Ähm ... Es überrascht mich, dass niemand erkannt hat, dass der Compiler den Test einfach optimiert und ein festes Ergebnis als Rückgabewert liefert. Dadurch werden alle obigen Codebeispiele praktisch unbrauchbar. Das einzige, was zurückgegeben werden würde, ist die Endianness zur Kompilierzeit! Und ja, ich habe alle oben genannten Beispiele getestet. Hier ist ein Beispiel mit MSVC 9.0 (Visual Studio 2008).
  Reiner C-Code
  Möglicherweise ist es möglich, die Kompilierzeitoptimierung für nur diese Funktion zu deaktivieren, aber ich weiß es nicht. Andernfalls ist es möglicherweise möglich, sie in Assembly fest zu codieren, obwohl dies nicht portabel ist. Und selbst dann könnte das optimiert werden. Ich denke, ich brauche einen wirklich beschissenen Assembler, den gleichen Code für alle vorhandenen CPUs/Befehlssätze und, na gut, egal.
  Jemand sagte hier auch, dass sich Endiananness während der Laufzeit nicht ändert. FALSCH. Es gibt dort bi-endian Maschinen. Ihre Endgültigkeit kann während der Ausführung variieren. AUCH gibt es nicht nur Little Endian und Big Endian, sondern auch andere Endianzen (was für ein Wort).
  Ich hasse und liebe es, gleichzeitig zu programmieren ...
  04.05.2011 Coriiander
  Ich war überrascht, dass niemand die Makros erwähnt hat, die der Vorprozessor standardmäßig definiert. Diese variieren je nach Plattform. Sie sind viel sauberer als Ihren eigenen Endian-Check schreiben zu müssen.
  Zum Beispiel; Wenn wir uns die eingebauten Makros ansehen, die GCC definiert (auf einem X86-64-Computer):
  Auf einer PPC Maschine bekomme ich:
  (Die :| gcc -dM -E -x c --Magie druckt alle integrierten Makros aus.).
  20.06.2009 DaveR
  Verwenden Sie jetzt char * -Punkte für verschiedene Teile und prüfen Sie, was sich in diesen Teilen befindet.
  Je nachdem, welches Byte auf 0xFF-Byte zeigt, können Sie die Endianness erkennen. Dies erfordert sizeof (int)> sizeof (char), gilt jedoch definitiv für die besprochenen Plattformen.
  16.06.2009 sharptooth
  Weitere Informationen hierzu finden Sie in diesem Artikel des Codeprojekts Grundlegende Konzepte zu Endianness :
  Wie wird der Endian-Typ zur Laufzeit dynamisch getestet?
  Wie in Computer Erläutert. Animations-FAQ können Sie die .__ verwenden. folgende Funktion, um zu sehen, ob Ihr Code läuft auf einem Little- oder Big-Endian System: Zusammenbruch
  Dieser Code weist einem .__ den Wert 0001h zu. 16-Bit-Ganzzahl Ein Zeichenzeiger ist dann zugewiesen auf den ersten (niederwertigstes) Byte des Integer Wert. Wenn das erste Byte von die ganze Zahl ist 0x01h, dann das System ist Little-Endian (0x01h steht in der niedrigsten oder niedrigstwertigen Adresse). Wenn es 0x00h ist, dann die System ist Big-Endian.
  16.06.2009 none
  Der C++ - Weg war die Verwendung von boost , bei der Präprozessorprüfungen und -umwandlungen in sehr sorgfältig getesteten Bibliotheken unterteilt sind.
  Die Predef Library (boost/predef.h) erkennt vier verschiedene Arten von Endianness .
  Die Endian Library sollte dem C++ - Standard übergeben werden und unterstützt eine Vielzahl von Operationen für sensible Daten.
  Wie in den Antworten oben erwähnt, wird Endianness Teil von c ++ 20 sein.
  11.09.2015 fuzzyTew
  Wenn Sie kein Framework verwenden, das auf PPC und Intel-Prozessoren portiert wurde, müssen Sie bedingte Kompilierungen durchführen, da PPC und Intel-Plattformen völlig unterschiedliche Hardwarearchitekturen, Pipelines, Busse usw. haben Dadurch wird der Assembly-Code zwischen den beiden völlig unterschiedlich.
  Um Endianness zu finden, gehen Sie wie folgt vor:
  Sie erhalten entweder TempChar als 0x12 oder 0x34, von der Sie die Endianness kennen.
  16.06.2009 samoz
  Wie oben erwähnt, verwende Unionstricks.
  Es gibt jedoch nur wenige Probleme mit den oben genannten, insbesondere, dass der unausgerichtete Speicherzugriff für die meisten Architekturen notorisch langsam ist, und einige Compiler erkennen solche konstanten Prädikate überhaupt nicht, es sei denn, Word ist ausgerichtet.
  Da der reine Endian-Test langweilig ist, gibt es hier eine (Vorlagen-) Funktion, die die Eingabe/Ausgabe einer beliebigen Ganzzahl gemäß Ihrer Spezifikation unabhängig von der Host-Architektur umdreht.
  Verwenden Sie zum Konvertieren von gegebenem Endian zu Host:
  Verwenden Sie zum Konvertieren von Host-Endian zu gegebenem Endian Folgendes:
  Der resultierende Code ist so schnell wie das Schreiben von hand Assembly auf clang, auf gcc etwas langsamer (nicht gerollt &, <<, >>, | für jedes Byte), aber immer noch anständig.
  12.10.2012 kat
  25.11.2012 Paolo Brandoli
  kompilierzeit, Nicht-Makro, C++ 11 Constexpr-Lösung:
  21.05.2014 zhaorufei
  Auf diese Weise erhalten Sie eine zeiteffiziente Funktion, die die Berechnung nur einmal durchführt.
  16.06.2009 Jeremy Mayhew
  ungeprüft, aber in meinem Kopf sollte das funktionieren? weil es auf Little Endian 0x01 und auf Big Endian 0x00 sein wird?
  14.02.2015 hanshenrik
  Dies ist eine andere Lösung. Ähnlich der Lösung von Andrew Hare.
  02.10.2012 Neeraj
  Sie können dies auch über den Präprozessor mit einer Boost-Header-Datei tun, die gefunden werden kann boost endian
  16.06.2009 nmushell
  Wenn der Endian-Header nur GCC ist, enthält er Makros, die Sie verwenden können.
  18.04.2015 Mark A. Libby
  Wenn Sie keine bedingte Kompilierung wünschen, können Sie einfach endian-unabhängigen Code schreiben. Hier ist ein Beispiel (aus Rob Pike ):
  Eine Ganzzahl, die in Little Endian auf der Festplatte gespeichert ist, wird auf unabhängige Weise gelesen:
  Derselbe Code, der versucht, die Endianness der Maschine zu berücksichtigen:
  17.02.2017 fjardon
  16.06.2009 Jon Bright
  16.06.2009 Abhay
  Die Art und Weise, in der C-Compiler (zumindest alle, die ich kenne) die Endannahme hat bearbeiten, die zur Kompilierzeit festgelegt wird. Selbst für biendianische Prozessoren (wie ARM und MIPS) müssen Sie beim Compilieren die Endianness auswählen. Darüber hinaus wird die Endianness in allen gängigen Dateiformaten für ausführbare Dateien (z. B. ELF) definiert. Obwohl es möglich ist, einen binären Blob aus biandianischem Code zu erstellen (für einige ARM Server-Exploite?), Muss er wahrscheinlich in Assembly ausgeführt werden.
  25.11.2012 Fabel
  Siehe Endianness - C-Level-Code-Abbildung.
  16.06.2009 gimel
  Keine union verwenden!
  C++ erlaubt kein Punning von Typen über unions!
  Lesen von einem Union-Feld, das nicht das letzte Feld war, in das geschrieben wurde, ist undefiniertes Verhalten !
  Viele Compiler unterstützen dies als Erweiterung, die Sprache gibt jedoch keine Garantie.
  Es gibt nur zwei gültige Antworten, die garantiert portabel sind.
  Die erste Antwort, wenn Sie Zugriff auf ein System haben, das C++ 20 unterstützt,
  soll std::endian aus dem <type_traits>-Header verwenden.
  (Zum Zeitpunkt des Schreibens wurde C++ 20 noch nicht veröffentlicht. Sofern sich jedoch etwas auf die Aufnahme von std::endian auswirkt, ist dies die bevorzugte Methode, um die Endianness ab C++ 20 zur Kompilierungszeit zu testen.)
  Ab C++ 20
  Vor C++ 20 besteht die einzig gültige Antwort darin, eine Ganzzahl zu speichern und dann das erste Byte durch Typ-Punning zu überprüfen.
  Im Gegensatz zur Verwendung von unions ist dies im Typensystem von C++ ausdrücklich erlaubt.
  Es ist auch wichtig zu bedenken, dass für eine optimale Portabilität static_cast verwendet werden sollte.
  weil reinterpret_cast implementierungsdefiniert ist.
  Wenn ein Programm versucht, über einen anderen Wert als einen der folgenden Typen auf den gespeicherten Wert eines Objekts zuzugreifen, ist das Verhalten undefiniert: ... ein Typ char oder unsigned char.
  Ab C++ 11
  Ab C++ 11 (ohne Aufzählung)
  17.05.2019 Pharap
  Hier ist eine andere C-Version. Es definiert ein Makro mit dem Namen wicked_cast() für Inline-Typ-Punning über C99-Unionsliterale und den nicht standardmäßigen __typeof__-Operator.
  Wenn Ganzzahlen Einzelbyte-Werte sind, macht endianness keinen Sinn und es wird ein Fehler bei der Kompilierung generiert.
  16.06.2009 Christoph
  es gibt zwar keine schnelle und standardisierte Methode, um dies zu bestimmen, dies wird jedoch ausgegeben: