Nie używaj union
!
C ++ nie zezwala na pisanie typu za pomocą union
s!
Czytanie z pola unii, które nie było ostatnim polem, do którego napisano, jest niezdefiniowanym zachowaniem !
Wiele kompilatorów obsługuje to jako rozszerzenia, ale język nie daje żadnej gwarancji.
Zobacz tę odpowiedź, aby uzyskać więcej informacji:
https://stackoverflow.com/a/11996970
Istnieją tylko dwie poprawne odpowiedzi, które z pewnością są przenośne.
Pierwszą odpowiedzią, jeśli masz dostęp do systemu obsługującego C ++ 20,
jest użycie std::endian
z <type_traits>
nagłówka.
(W momencie pisania C ++ 20 nie został jeszcze wydany, ale chyba że coś wpłynie na std::endian
włączenie, będzie to preferowany sposób testowania endianizmu w czasie kompilacji od C ++ 20 wzwyż.)
C ++ 20 i więcej
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
Przed wersją C ++ 20 jedyną prawidłową odpowiedzią jest zapisanie liczby całkowitej, a następnie sprawdzenie pierwszego bajtu za pomocą znakowania punktowego.
W przeciwieństwie do użycia union
s, jest to wyraźnie dozwolone przez system typów C ++.
Ważne jest również, aby pamiętać, że dla optymalnej przenośności static_cast
należy użyć,
ponieważ reinterpret_cast
jest zdefiniowana implementacja.
Jeśli program próbuje uzyskać dostęp do zapisanej wartości obiektu za pośrednictwem wartości innej niż jeden z następujących typów, zachowanie jest niezdefiniowane: ... a char
lub unsigned char
type.
C ++ 11 i dalsze
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;
}
C ++ 11 i więcej (bez wyliczenia)
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);
}