假设我有一些如下定义的结构:
struct foo { int a; };
struct bar { struct foo r; int b; };
struct baz { struct bar z; int c; };
C标准是否保证以下代码是严格符合规范的?
struct baz x;
struct foo *p = (void *)&x;
assert(p == &x.z.r);
这种构造的动机是提供一致的编程习语,用于将已知兼容的指针类型转换为指针类型。
下面是C语言关于结构体及其初始成员可转换性的说明:
在一个结构体对象中,非位字段成员和位字段所在的单元的地址按照它们声明的顺序递增。适当转换后,指向结构体对象的指针指向其初始成员(或如果该成员是位字段,则指向其中所在的单元),反之亦然。结构体对象中可能有未命名的填充,但不会位于其开始处。
C.11 §6.7.2.1¶15
这是关于 void
指针转换的说明:
指向
void
的指针可以转换为任何对象类型的指针,也可以从任何对象类型的指针转换为指向void
的指针;结果应与原始指针相等。
C.11 §6.3.2.3¶1
这是关于对象指针类型之间转换的说明:
对象类型的指针可以转换为不同对象类型的指针。如果结果指针未针对引用的类型正确对齐68),则行为未定义。否则,在再次转换时,结果应与原始指针相等。
68) 通常情况下,“正确对齐”概念是可传递的:如果对类型A的指针对于对类型B的指针正确对齐,并且对类型B的指针对于对类型C的指针正确对齐,则对类型A的指针对于对类型C的指针正确对齐。
C.11 §6.3.2.3¶7
从上面的内容中我理解,通过 void *
转换将对象指针转换为不同类型的对象指针是完全可以的。但是,我得到了一个意见表明这种转换是不合适的。
void *
进行强制转换也无法改变这一点。 - Crowman