Краткий ответ:
Если вы не знаете, что означает reinterpret_cast
, не используйте его. Если вам это понадобится в будущем, вы узнаете.
Полный ответ:
Давайте рассмотрим основные типы чисел.
Когда вы преобразуете, например, int(12)
в unsigned float (12.0f)
, ваш процессор должен вызвать некоторые вычисления, поскольку оба числа имеют разное представление битов. Вот что означает static_cast
.
С другой стороны, когда вы вызываете reinterpret_cast
, ЦП не вызывает никаких вычислений. Он просто обрабатывает набор битов в памяти, как если бы он имел другой тип. Поэтому при преобразовании int*
в float*
с этим ключевым словом новое значение (после разыменования указателя) не имеет ничего общего со старым значением в математическом смысле.
Пример: Это правда, что reinterpret_cast
не является переносимым по одной причине - порядку байтов (порядку байтов). Но это часто удивительно лучшая причина для его использования. Давайте представим пример: вы должны прочитать двоичное 32-битное число из файла, и вы знаете, что это порядковый номер. Ваш код должен быть универсальным и работать должным образом в системах с прямым порядком байтов (например, в некоторых ARM) и байтовых порядках (например, в x86). Таким образом, вы должны проверить порядок байтов. Это хорошо известно во время компиляции, поэтому вы можете написать constexpr
function: Вы можете написать функцию для достижения этой цели:
/*constexpr*/ bool is_little_endian() {
std::uint16_t x=0x0001;
auto p = reinterpret_cast<std::uint8_t*>(&x);
return *p != 0;
}
Объяснение: двоичное представление x
в памяти может быть 0000'0000'0000'0001
(большое) или 0000'0001'0000'0000
(младший порядок). После реинтерпретации приведение байта под указатель p
может быть соответственно 0000'0000
или 0000'0001
. Если вы используете статическое приведение, оно всегда будет 0000'0001
, независимо от того, какой порядковый номер используется.
EDIT:
В первой версии я сделал пример функции is_little_endian
равной constexpr
. Он прекрасно компилируется на новейшем gcc (8.3.0), но стандарт говорит, что это незаконно. Компилятор clang отказывается компилировать его (что правильно).