Verwenden Sie kein union
!
C ++ erlaubt kein Typ-Punning über union
s!
Das Lesen aus einem Gewerkschaftsfeld, in das nicht das letzte Feld geschrieben wurde, ist undefiniertes Verhalten !
Viele Compiler unterstützen dies als Erweiterung, aber die Sprache übernimmt keine Garantie.
Siehe diese Antwort für weitere Details:
https://stackoverflow.com/a/11996970
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,
ist die Verwendung std::endian
über den <type_traits>
Header.
(Zum Zeitpunkt des Schreibens war C ++ 20 noch nicht veröffentlicht. Sofern jedoch nichts die std::endian
Aufnahme beeinflusst, ist dies die bevorzugte Methode, um die Endianness zur Kompilierungszeit ab C ++ 20 zu testen.)
Ab C ++ 20
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
Vor C ++ 20 besteht die einzig gültige Antwort darin, eine Ganzzahl zu speichern und dann ihr erstes Byte durch Typ Punning zu überprüfen.
Im Gegensatz zur Verwendung von union
s ist dies vom C ++ - Typsystem ausdrücklich zulässig.
Es ist auch wichtig zu bedenken, dass für eine optimale Portabilität static_cast
verwendet werden sollte,
da reinterpret_cast
die Implementierung definiert 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: ... a char
oder unsigned char
Typ.
Ab C ++ 11
enum class endianness
{
little = 0,
big = 1,
};
inline endianness get_system_endianness()
{
const int value { 0x01 };
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01) ? endianness::little : endianness::big;
}
Ab C ++ 11 (ohne Aufzählung)
inline bool is_system_little_endian()
{
const int value { 0x01 };
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01);
}
C ++ 98 / C ++ 03
inline bool is_system_little_endian()
{
const int value = 0x01;
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01);
}