很明显,在C cannot insert padding between their elements中的数组。但是,是否有任何规则说他们不能在整个阵列的尾端处添加尾部填充?数组可以有尾部填充吗?
即,这个程序保证在任何地方都能得到相同的结果吗?
#include <stdio.h>
int main(void) {
typedef char a[3];
typedef a b[3];
printf("%zu %zu\n", sizeof(a), sizeof(b)); // -> 3 9
}
至于我可以工作,加入了尾随字节或五的a
大小,也许在一个错误的优化的尝试,就不会突破数组访问规则(b[1][1]
仍然恰好映射到*(&b + sizeof(a) * 1 + 1)
不管其包含的a
对象的大小,并且访问超出所包含的a
的长度是UB)。
我找不到在C标准中的任何地方,它实际上说直接说数组的大小是元素类型的大小乘以元素的数量。 6.5.3.4只说sizeof
返回数组中的“字节数”(它确实给出sizeof array/sizeof array[0]
作为代码示例,但它只是一个示例 - 它并不是说它必须工作,它不给出任何细节)。
隐式保证对于编写依赖于确切数据布局的便携式代码很有用,例如,经过打包的RGB值:
typedef uint8_t RGB[3];
RGB * data = ...;
glColorPointer(3, GL_UNSIGNED_BYTE, 0, data);
(OK这样的OpenGL可以接受步幅值,所以这是一个坏榜样,但你明白了吧)
对于这个问题,我从广泛的概念(即使假设标准中的例子),你可以用sizeof
得到一个数组元素的数量,无论如何这在任何地方都可能是真的 - 是否有任何已知的情况?
填充的含义是使数据对齐。在你的情况下,我相信所有3的char数组的大小都是3,但如果你在之后声明一个int,那么可能会有1或5个填充。一个好的c编译器不会做额外的工作,这很难预测。但如果您谈论的是可移植性,我认为最好是在目标平台上重新编译代码,或者如果平台差异很大,则可以进行交叉编译。 – HuStmpHrrr 2014-11-23 19:36:48
“,并没有给出任何细节” - 它确实说计算数组中的元素数量。你说得对,那只是一个例子,而这个例子并不是规范的。 – hvd 2014-11-23 19:39:26
通过查看后续子句,可以间接推断出数组没有这种填充:“当应用于具有结构或联合类型的操作数时,结果是此类对象中的总字节数,包括内部和尾部填充。” - 在结构和联合中显式引用了填充,而在数组中缺少这种引用使我相信数组中不能有这种填充。 – 2014-11-23 19:41:32