Не використовуйте union
!
C ++ не дозволяє тип покарання через union
s!
Читання з профспілкового поля, яке не було останнім полем, для якого було записано, - це невизначена поведінка !
Багато компіляторів підтримують це як розширення, але мова не дає гарантій.
Дивіться цю відповідь для отримання більш детальної інформації:
https://stackoverflow.com/a/11996970
Є лише два дійсні відповіді, які гарантовано є портативними.
Перша відповідь, якщо у вас є доступ до системи, яка підтримує C ++ 20,
- це використовувати std::endian
з <type_traits>
заголовка.
(На момент написання повідомлення C ++ 20 ще не було випущено, але якщо щось не вплине std::endian
на включення, це є кращим способом перевірити витривалість під час компіляції від C ++ 20).
C ++ 20 і далі
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
До C ++ 20, єдиною правильною відповіддю є збереження цілого числа, а потім перевірка його першого байта за допомогою тиску накачування.
На відміну від використання union
s, це чітко дозволено системою типів C ++.
Важливо також пам’ятати, що для оптимальної портативності static_cast
слід використовувати,
оскількиreinterpret_cast
це визначено реалізацією.
Якщо програма намагається отримати доступ до збереженого значення об'єкта за допомогою glvalue іншого, ніж одного з наступних типів, поведінка не визначена: ... a char
абоunsigned char
type.
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;
}
C ++ 11 далі (без перерахунку)
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);
}