KBl*_*Blr 14 c language-lawyer
我的结构如下.
struct result{
int a;
int b;
int c;
int d;
}
Run Code Online (Sandbox Code Playgroud)
和联盟如下.
union convert{
int arr[4];
struct result res;
}
Run Code Online (Sandbox Code Playgroud)
我输入双关语如下.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %d\n", pointer->res.a, pointer->res.b);
Run Code Online (Sandbox Code Playgroud)
Bat*_*eba 11
pointer->res.a很好,但行为pointer->res.b是不确定的.
在a和b成员之间可以有任意数量的填充.
有些编译器允许您指定成员之间没有填充,但当然您放弃了可移植性.
这种类型是否很明确?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
Run Code Online (Sandbox Code Playgroud)
(union convert *) arr1 风险调整失败.
指向对象类型的指针可以转换为指向不同对象类型的指针.如果生成的指针未针对引用的类型正确对齐,则行为未定义.C11dr§6.3.2.38
没有要求union convert和int共享相同的对齐方式.union convert要求可能超过int例如.
考虑这种可能性:arr1[]住在int街上,所有的地址都多的4 union和struct朋友住在街"的8个多". arr1[]可能有地址0x1004(不是8的倍数).
在2019年,对齐失败更常见于char(需要1)和需要2或更多的其他类型.在OP的选择案例中,我怀疑真正的平台是否会出现对齐问题,但仍然可能出现错误对齐.
这种类型的惩罚没有明确定义.
其他问题
其他答案和评论讨论填充问题,进一步确定问题.
@Eric Postpischil约妄加评说访问与pointer->res.a增加了更多的理由来考虑这个UB.