这种类型是否很明确?

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是不确定的.

ab成员之间可以有任意数量的填充.

有些编译器允许您指定成员之间没有填充,但当然您放弃了可移植性.

  • `pointer-> res.a`通过左值(`pointer-> res`)访问一个对象(`arr1`),违反C 2018 6.5 7. (3认同)

chu*_*ica 6

这种类型是否很明确?

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 convertint共享相同的对齐方式.union convert要求可能超过int例如.

考虑这种可能性:arr1[]住在int街上,所有的地址都多的4 unionstruct朋友住在街"的8个多". arr1[]可能有地址0x1004(不是8的倍数).

在2019年,对齐失败更常见于char(需要1)和需要2或更多的其他类型.在OP的选择案例中,我怀疑真正的平台是否会出现对齐问题,但仍然可能出现错误对齐.

这种类型的惩罚没有明确定义.


其他问题

其他答案和评论讨论填充问题,进一步确定问题.

@Eric Postpischil约妄加评说访问pointer->res.a增加了更多的理由来考虑这个UB.