C struct:没有填充的连续字段?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C struct:没有填充的连续字段?相关的知识,希望对你有一定的参考价值。
any_t
是任何类型(int
,struct 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]);
是否保证val
和array
之间不会添加填充?
答案
仅从C标准来看,由于以下原因,使用&v.val
作为11个any_t
阵列是不安全的:
- C标准允许在结构中使用未命名的内部填充:C 2011(N1570)6.7.2.1 15,“结构对象中可能有未命名的填充,但不是在其开头。”C实现插入填充是不常见的在
val
和array
之间,因为对齐要求不需要它,但它是允许的,并且在某些情况下可以想象它是有益的,例如使array
更好地与性能(而不是必要性)对齐。 - 即使有保证
val
和array
元素的间距与11any_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]
的赋值视为独立的,并以任何顺序执行它们,即使你可能设置了i
和j
以便它们指向相同的元素。
另一答案
不,标准没有任何保证。但是,您的特定编译器实现当然可以提供超出标准所做的保证。查看您的文档以获取所有详细信息。
另一答案
那么你对struct的定义大概是2个字段,所以你的计算机可能不会将它用作11个元素的arry,所以你必须在声明它们时填充你的文件。
以上是关于C struct:没有填充的连续字段?的主要内容,如果未能解决你的问题,请参考以下文章