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

时间:2013-07-22 13:06:45

标签: c struct padding

any_t是任何类型(intstruct something,...)。

考虑这个结构:

struct my_struct {
    any_t val,
    any_t array[10]
}

如果我定义变量v

struct my_struct v;

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

any_t *p = &v.val;
f(p[0]);
f(p[5]);
f(p[10]);

是否保证在valarray之间不会添加填充?

3 个答案:

答案 0 :(得分:7)

单凭C标准,出于以下原因,将&v.val用作11 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以便他们指向相同的元素。

答案 1 :(得分:1)

不,标准没有保证。但是,您的特定编译器实现当然可以提供超出标准所做的保证。查看您的文档以获取所有详细信息。

答案 2 :(得分:0)

你对结构的定义是关于2个字段的,所以你的编纂者可能不会将它用作11个元素的arry,所以你必须填写你的文件,因为它们被删除。