¡No utilices a union
!
C ++ no permite la escritura de tipos a través de union
s!
¡Leer desde un campo sindical que no fue el último campo escrito es un comportamiento indefinido !
Muchos compiladores admiten hacerlo como extensiones, pero el lenguaje no garantiza.
Vea esta respuesta para más detalles:
https://stackoverflow.com/a/11996970
Solo hay dos respuestas válidas que están garantizadas para ser portátiles.
La primera respuesta, si tiene acceso a un sistema que admite C ++ 20,
es usarlo std::endian
desde el <type_traits>
encabezado.
(Al momento de escribir, C ++ 20 aún no se ha lanzado, pero a menos que algo afecte std::endian
la inclusión, esta será la forma preferida de probar la resistencia en tiempo de compilación desde C ++ 20 en adelante).
C ++ 20 en adelante
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
Antes de C ++ 20, la única respuesta válida es almacenar un número entero y luego inspeccionar su primer byte a través del tipo punteo.
A diferencia del uso de union
s, esto está expresamente permitido por el sistema de tipos de C ++.
También es importante recordar que para una portabilidad óptima se static_cast
debe usar,
porque la reinterpret_cast
implementación está definida.
Si un programa intenta acceder al valor almacenado de un objeto a través de un valor gl diferente de uno de los siguientes tipos, el comportamiento es indefinido: ... a char
o unsigned char
tipo.
C ++ 11 en adelante
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 en adelante (sin enumeración)
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);
}