4
int i = 42;
int *p1 = &i;
int long *p2 = (long*)p1;

这是未定义的行为吗?在 C++ 中,我认为出于某种原因它是实现定义的行为。

我查看了 C 标准:

C99 6.3.2.3/7 指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。如果结果指针未正确对齐 57) 指向的类型,则行为未定义。否则,当再次转换回来时,结果将等于原始指针。

57) 一般来说,“正确对齐”的概念是可传递的:如果指向类型 A 的指针正确对齐指向类型 B 的指针,而指向类型 B 的指针又正确对齐指向类型 C 的指针,则指向类型 A 的指针是为指向 C 类型的指针正确对齐。

在实践中,术语正确对齐是什么意思?你怎么知道你是否正确地执行了它而不进入未定义的行为?

4

1 回答 1

4

这基本上意味着,如果int对齐到 4 个字节,并且int long对齐到 8 个字节,那么行为是未定义的。假设你有类似的东西:

 0x04     0x08    0x0C    0x10
+------+-------+-------+-------+
|      |       |   i   |       |
+------+-------+-------+-------+

在这种情况下,&i == 0x0C(这是有效的,因为int对齐到 4 个字节)。当您int long*转换为 时,指针将转换为对齐的:p2 == 0x08,因为我们的理论系统对齐int long到 8 个字节,所以如果您取消引用,您基本上会读取一个您不拥有的地址p1,因此未定义的行为。

于 2012-12-04T04:47:55.770 回答