特定类型指针能否赋值给包含该类型成员的联合体指针?
关于联合体指针与首个成员指针转换的安全性问题
先看定义的结构体与联合体代码:
struct Foo { int i; float f; }; union Bar { struct Foo foo; char buf[10]; };
再看待验证的操作代码:
struct Foo fooVar; union Bar* barPtrVar = (union Bar*) &fooVar; barPtrVar->foo.i = 1000; barPtrVar->foo.f = 0.5f;
这种操作是安全的,理由如下:
- C语言明确规定,联合体对象的地址和它首个成员的地址完全一致。这和结构体的规则类似——结构体指针能和首个成员指针互换,联合体这边也适用同样逻辑,首个成员的指针和联合体指针可以安全转换。
- 这里
union Bar的第一个成员就是struct Foo foo,把fooVar的地址强制转成union Bar*后,通过这个指针访问barPtrVar->foo,其实就是直接操作原来的fooVar对象。两者内存起始位置完全对齐,成员布局也完全匹配,不会触发内存越界或者类型不兼容的未定义行为。 - 需要注意:如果后续用这个
union Bar*去访问buf成员,就会触发未定义行为——struct Foo的大小通常是8字节,而buf是10字节,访问超出fooVar内存范围的部分属于非法操作。但题目明确限定了“仅通过该指针操作union Bar的foo成员”,所以这种场景下完全安全。
内容的提问来源于stack exchange,提问作者Neutral Effect
相关产品推荐
相关产品推荐

