假设short
是2个字节,而int
是32位操作系统上的4个字节。以下是未定义的行为吗?
short s = 42;
int *p = (int*)(&s);
答案 0 :(得分:7)
不,您发布的代码未显示未定义的行为,但尝试阅读*p
会。此外,根据int
和short
的对齐要求,演员的结果可能未指定且不可逆转(见5.2.10 [expr.reinterpret.cast] / 7)。
见ISO / IEC 14882:2011 3.10 [basic.lval] / 10:
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- 对象的动态类型,
- 对象的动态类型的cv限定版本,
- 与对象的动态类型相似的类型(如4.4中所定义)
- 与对象的动态类型对应的有符号或无符号类型的类型
- 与对象的动态类型的cv限定版本对应的有符号或无符号类型的类型,
- 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合或包含联合的元素或非静态数据成员),
- 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
- char或unsigned char类型。
您尝试访问的对象是short
,*p
是int
类型的 glvalue ,它不符合上述任何条件描述。
答案 1 :(得分:1)
您的代码直接位于UB领域,因为您正在读取两个未初始化的字节。 然而,相反,
int b
short* f = (short *) &b
由于小端架构的语义,可能会起作用。
(这都是假设编译器没有做任何愚蠢的事情)
来自维基百科:
little-endian系统具有相同值的属性 从不同长度的内存读取而不使用不同的 地址(即使在施加对齐限制时)。例如, 可以在中读取内容为4A 00 00 00的32位内存位置 与8位(值= 4A),16位(004A),24位相同的地址 (00004A)或32位(0000004A),所有这些都保留相同的数字 值。虽然这个little-endian属性很少直接使用 高级程序员,它通常被代码优化器用作 以及汇编语言程序员。
所以,只要你是小端,相反的方向应该没问题。
但仍未定义行为。