Non usare a union
!
C ++ non consente la punzonatura di tipo tramite union
s!
Leggere da un campo sindacale che non era l'ultimo campo scritto è un comportamento indefinito !
Molti compilatori lo supportano come estensioni, ma la lingua non offre alcuna garanzia.
Vedi questa risposta per maggiori dettagli:
https://stackoverflow.com/a/11996970
Ci sono solo due risposte valide che sono garantite come portatili.
La prima risposta, se si ha accesso a un sistema che supporta C ++ 20,
è utilizzare std::endian
dall'intestazione <type_traits>
.
(Al momento in cui scrivo, C ++ 20 non è ancora stato rilasciato, ma a meno che non accada qualcosa che influisca std::endian
sull'inclusione, questo sarà il modo preferito per testare l'endianità al momento della compilazione da C ++ 20 in poi.)
C ++ 20 in poi
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
Prima di C ++ 20, l'unica risposta valida è quella di memorizzare un numero intero e quindi ispezionare il suo primo byte tramite la punzonatura del tipo.
A differenza dell'uso di union
s, ciò è espressamente consentito dal sistema di tipi di C ++.
È anche importante ricordare che per la portabilità ottimale static_cast
dovrebbe essere usato,
perché reinterpret_cast
è definita l'implementazione.
Se un programma tenta di accedere al valore memorizzato di un oggetto attraverso un valore diverso da uno dei seguenti tipi, il comportamento non è definito: ... a char
o unsigned char
tipo.
C ++ 11 in poi
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 in poi (senza enum)
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);
}