Não use a union
!
C ++ não permite punção de tipo via union
s!
Ler de um campo de união que não foi o último campo gravado é um comportamento indefinido !
Muitos compiladores suportam isso como extensões, mas o idioma não garante.
Veja esta resposta para mais detalhes:
https://stackoverflow.com/a/11996970
Existem apenas duas respostas válidas que são garantidas como portáteis.
A primeira resposta, se você tiver acesso a um sistema que suporte C ++ 20,
será usar std::endian
o <type_traits>
cabeçalho.
(No momento em que este artigo foi escrito, o C ++ 20 ainda não foi lançado, mas, a menos que algo afete std::endian
a inclusão, essa deve ser a maneira preferida de testar o endianness no tempo de compilação a partir do C ++ 20).
C ++ 20 em diante
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
Antes do C ++ 20, a única resposta válida é armazenar um número inteiro e, em seguida, inspecionar seu primeiro byte por meio de punção de tipo.
Diferentemente do uso de union
s, isso é expressamente permitido pelo sistema de tipos do C ++.
Também é importante lembrar que a portabilidade ideal static_cast
deve ser usada,
porque a reinterpret_cast
implementação está definida.
Se um programa tentar acessar o valor armazenado de um objeto por meio de um valor gl gl diferente de um dos seguintes tipos, o comportamento será indefinido: ... a char
ou unsigned char
type.
C ++ 11 em diante
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 em diante (sem enumeração)
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);
}