在 ISO/IEC 9899:TC2 中,标准规定如下
6.3.2.3 指针
- 指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。如果结果指针未正确对齐指向的类型,则行为未定义。否则,当再次转换回来时,结果将等于原始指针。当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指向对象剩余字节的指针。
因此,从标准中不清楚可以将一种类型的指针转换为另一种类型的指针。
在 ISO/IEC 9899:TC2 中,标准规定如下
6.3.2.3 指针
- 指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。如果结果指针未正确对齐指向的类型,则行为未定义。否则,当再次转换回来时,结果将等于原始指针。当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指向对象剩余字节的指针。
因此,从标准中不清楚可以将一种类型的指针转换为另一种类型的指针。
严格的别名规则在其他地方定义。这是措辞:
C (ISO/IEC 9899:1999 6.5/7):
对象的存储值只能由具有以下类型之一的左值表达式访问:
- 与对象的有效类型兼容的类型,
- 与对象的有效类型兼容的类型的限定版本,
- 与对象的有效类型相对应的有符号或无符号类型,
- 对应于对象有效类型的限定版本的有符号或无符号类型,
- 聚合或联合类型,在其成员中包含上述类型之一(递归地包括子聚合或包含联合的成员),或
- 一种字符类型。
C++(ISO/IEC 14882:2011 3.10 [basicl.lval] / 15):
如果程序尝试通过以下类型之一以外的左值访问对象的存储值,则行为未定义:
- 对象的动态类型,
- 对象的动态类型的 cv 限定版本,
- 与对象的动态类型类似(如 4.4 中定义)的类型,
- 与对象的动态类型相对应的有符号或无符号类型,
- 对应于对象动态类型的 cv 限定版本的有符号或无符号类型,
- 聚合或联合类型,在其元素或非静态数据成员中包括上述类型之一(递归地包括子聚合或包含联合的元素或非静态数据成员),
- 一个类型,它是对象的动态类型的(可能是 cv 限定的)基类类型,
- 一个
char
或unsigned char
类型。
C 标准不禁止您将指针转换为不相关的类型,前提是没有对齐问题。但是,由于严格的别名规则,您基本上不能取消引用从这种转换获得的指针。因此,对这种“无效”指针唯一有用的是将其转换回正确的类型(或兼容的类型)。
它在 C++ 中与 reinterpret_cast (5.2.10 [expr.reinterpret.cast] / 7)基本相同:
对象指针可以显式转换为不同类型的对象指针。当
v
“pointer toT1
”类型的纯右值转换为“pointer to cvT2
”类型时,结果是static_cast<cv T2*>(static_cast<cv void*>(v))
如果T1
和T2
都是标准布局类型(3.9)并且 的对齐要求T2
不比 的更严格T1
,或者如果任一类型是void
。将“pointer to”类型的纯右值转换为“pointer toT1
”类型T2
(其中T1
和T2
是对象类型,其中 的对齐要求T2
不比 的 更严格T1
)并返回其原始类型会产生原始指针值。未指定任何其他此类指针转换的结果。