C struct:没有填充的连续字段?

rom*_*m1v 4 c struct padding

any_t是任何类型的(int,struct something,...).

考虑这个结构:

struct my_struct {
    any_t val,
    any_t array[10]
}
Run Code Online (Sandbox Code Playgroud)

如果我定义一个变量v:

struct my_struct v;
Run Code Online (Sandbox Code Playgroud)

&v.val作为11 any_t项的数组使用是否安全?

any_t *p = &v.val;
f(p[0]);
f(p[5]);
f(p[10]);
Run Code Online (Sandbox Code Playgroud)

是否保证不会在val和之间添加填充array

Eri*_*hil 7

仅从C标准来看,出于以下原因使用&v.val11作为数组是不安全的any_t:

  • C标准允许在结构中使用未命名的内部填充:C 2011(N1570)6.7.2.1 15,"结构对象中可能有未命名的填充,但不是在其开头."C实现插入填充是不常见的之间valarray,因为对齐要求将不需要它,但它是允许的,它是在某些情况下,如引起令人信服利于array为性能更好的对齐(而不是必然).
  • 即使有保证间距valarray元素与11的数组相同any_t,也无法保证指针算法有效.C 2011(N1570)6.5.6 8定义了指针算法(包括数组索引),它只要求数组内的算术工作(包括末尾的一个名义元素).一些C实现使用基址和偏移量寻址.在这种情况下,基地址val可能无法支持延伸到的偏移量array.
  • 即使C实现使用简单的平面寻址,也允许其优化器根据C标准进行推断.理论上,优化器可以看到指针是从地址派生的val,因此不能(根据C标准)用于解决任何问题array.例如,如果你这样做any_t *p = &v.val; p[i] = 3; v.array[j] = 4;,优化可以治疗的分配,以v.array[j]p[i]为独立和按任何顺序执行它们,即使你可能已设置ij让他们将指向同一个元素.