Противоинтуитивный эффект reinterpret_cast <T>

0

У меня есть следующий код:

std::vector<short> vec{ 0, 2, 0, 4 };
int* lpvec = reinterpret_cast<int*>(&vec[0]);

(Скомпилировано под VC12: короткие 2 байта, int 4 байта) Я думаю, что он будет производить:

lpvec[0] = 2, 
lpvec[1] = 4

но это меня удивляет и выносит

lpvec[0] = 2 * 2^16 + 0 = 131072, 
lpvec[1] = 4 * 2^16 + 0 = 262144

Я сказал контр-интуитивно, потому что я думаю, что вектор шорт выкладывается в памяти по следующей схеме:

+---------+---------+---------+---------+
| 2 bytes | 2 bytes | 2 bytes | 2 bytes |
+---------+---------+---------+---------+
|       0 |       2 |       0 |       4 |
+---------+---------+---------+---------+

поэтому int будет выглядеть одинаково, но занимает в два раза больше места:

+-------------+------------+
|   4 bytes   |  4 bytes   |
+-------------+------------+
| 0*2^16 + 2  | 0*2^16 + 4 |
+-------------+------------+

Кто-нибудь просветит меня, почему я ошибаюсь?

  • 7
    Вы думаете, большой порядок байтов. Твоя машина нет.
  • 2
    Посмотрите разницу между прямым и старшим порядком байтов .
Показать ещё 5 комментариев
Теги:
reinterpret-cast

1 ответ

8
Лучший ответ

Ой, это не круто...

То, что вы делаете, вызывает неопределенное поведение.

Приведение short* в int* нарушало бы правила псевдонимов, но в первую очередь "неожиданный" результат был обусловлен реализацией, определяемой конъюнкцией интегральных значений.


Little- против Big-Endian

"Endianness" - это порядок байтов (представляющих значение), хранящихся внутри интегрального типа, в этом случае int.

Кажется, что ваша платформа использует Little- endian; это означает, что младший байт сохраняется первым, а ваш ожидаемый результат зависит от реализации с использованием big-endian; который, как указано, не соответствует действительности.


Ваша реализация хранит short { 2 } как [0x02][0x00], что сделает int указывает lpvec эквивалентный [0x00][0x00][0x02][0x00].

В расчетах участвуют, так как ваша платформа использует big-endian:

(2^0 * 0) + (2^8 * 0) + (2^16 * 2) + (2^24 * 0) = 131072

Примечание: вышесказанное предполагает, что байт имеет ширину 8 бит, что также определяется реализацией.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню