reinterpret_cast <T>的反直觉效果

use*_*229 0 c++ reinterpret-cast

我有以下代码:

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

(在VC12下编译:短2个字节,int 4个字节)我认为它会产生:

lpvec[0] = 2, 
lpvec[1] = 4
Run Code Online (Sandbox Code Playgroud)

但它让我感到惊讶和输出

lpvec[0] = 2 * 2^16 + 0 = 131072, 
lpvec[1] = 4 * 2^16 + 0 = 262144
Run Code Online (Sandbox Code Playgroud)

我说反直觉,因为我认为短裤的矢量以下列模式在内存中排列:

+---------+---------+---------+---------+
| 2 bytes | 2 bytes | 2 bytes | 2 bytes |
+---------+---------+---------+---------+
|       0 |       2 |       0 |       4 |
+---------+---------+---------+---------+
Run Code Online (Sandbox Code Playgroud)

所以,int看起来会一样,但占用的空间是原来的两倍:

+-------------+------------+
|   4 bytes   |  4 bytes   |
+-------------+------------+
| 0*2^16 + 2  | 0*2^16 + 4 |
+-------------+------------+
Run Code Online (Sandbox Code Playgroud)

有人会启发我为什么我错了吗?

Fil*_*efp 8

哦,不,这不酷...

你正在做的是调用未定义的行为.

转换为short*to int*会违反别名规则,但主要是"意外"结果是由于实现定义了整数值的字节顺序.


Little-vs 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
Run Code Online (Sandbox Code Playgroud)

注意:上面假设一个字节是8位宽,这也是实现定义的.