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的指针正确对齐。
在这里,正确对齐一词在实践中意味着什么?如何知道您是否正在正确执行它而不会进入未定义的行为状态?
p2
进行解引用,那么这将是未定义的行为。原因是:您违反了严格别名规则。 - Mysticialint long *p2
这里的long
是什么意思? - Krishnabhadraint long *p2
是一种合法但略微不正规的写法,等同于signed long int *p2
、long *p2
、long int *p2
或long int signed *p2
(它们之间都是等价的)。 - Jonathan Leffleri
有很大可能会对齐到32位奇数地址边界,但是long
必须对齐到64位地址边界(或者32位偶数地址边界)。因此,在这样的系统上,如果您尝试通过p2
读取或修改内存,则会收到SIGBUS错误。 - Jonathan Leffler