int i = 42;
int *p1 = &i;
int long *p2 = (long*)p1;
这是未定义的行为吗?在C ++中,我认为由于某种原因它是实现定义的行为。
我看了C标准:
C99 6.3.2.3/7指向对象或不完整类型的指针可能是 转换为指向不同对象或不完整类型的指针。如果 对于指向的结果指针未正确对齐57) 类型,行为是未定义的。否则,再转换回来时, 结果应该等于原始指针。
57)一般来说,“正确对齐”的概念是可传递的:如果a 指向类型A的指针正确对齐指向类型B的指针 反过来正确对齐指向类型C的指针,然后是指针 对于指向类型C的指针,类型A正确对齐。
正确对齐的术语在实践中意味着什么?如果没有步入未定义的行为,你怎么知道你是否正确地做到了?
答案 0 :(得分:3)
它基本上意味着,如果int
与4个字节对齐,int long
与8个字节对齐,则行为未定义。说你有类似的东西:
0x04 0x08 0x0C 0x10
+------+-------+-------+-------+
| | | i | |
+------+-------+-------+-------+
在这种情况下,&i == 0x0C
(有效,因为int
与4个字节对齐)。当你转换为int long*
时,指针将被转换为对齐的指针:p2 == 0x08
,因为我们的理论系统将int long
对齐到8个字节,所以你基本上是在读取一个地址你如果你取消引用p1
,那就不要拥有,而不是未定义的行为。