数组可以有尾随填充吗? [英] Can an array have trailing padding?

查看:66
本文介绍了数组可以有尾随填充吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很明显,C中的数组无法在其元素之间插入填充.但是,是否有任何规则说他们不能在整个数组的 end 处添加尾随填充?

It is clear that arrays in C cannot insert padding between their elements. However, is there any rule saying that they can't add trailing padding at the end of the array as a whole?

即该程序可以保证在任何地方都提供相同的结果吗?

i.e. is this program guaranteed to give the same results everywhere?

#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的大小上添加尾随字节或5个字节,这不会破坏数组访问规则(b[1][1]仍精确映射到而不考虑其包含的a对象的大小,并且访问超出包含的a的长度都是UB.

As far as I can work out, adding a trailing byte or five to the size of a, perhaps in a misguided optimization attempt, wouldn't break the array access rules (b[1][1] still maps exactly to *(&b + sizeof(a) * 1 + 1) regardless of the size of its contained a objects, and accessing beyond the length of a contained a is UB anyway).

在C标准中,我找不到一个真正的地方,即数组的大小是元素类型的大小乘以元素数量. 6.5.3.4仅说sizeof返回数组中的字节数"(它确实给出了sizeof array / sizeof array[0]作为代码示例,但这只是一个示例-它没有说必须工作,但未提供任何详细信息.)

I can't find anywhere in the C standard where it actually says outright that the size of an array is the size of the element type multiplied by the number of elements. 6.5.3.4 only says that sizeof returns the "number of bytes" in the array (it does give sizeof array / sizeof array[0] as a code example, but it's only an example - it doesn't say it has to work, and it doesn't give any details).

隐式保证对于编写依赖于精确数据布局的可移植代码很有用,例如传递压缩的RGB值:

The implicit guarantee is useful for writing portable code that depends on exact data layouts, e.g. passing packed RGB values:

typedef uint8_t RGB[3];
RGB * data = ...;
glColorPointer(3, GL_UNSIGNED_BYTE, 0, data);

(好的,因此OpenGL可以接受跨步值,所以这是一个不好的例子,但您明白了)

(OK so OpenGL can accept stride values so this is a bad example, but you get the point)

为此,我假设从广泛的观念(甚至是标准中的示例)出发,您都可以使用sizeof来获得数组的元素数量,无论如何,这很可能适用于任何地方-是否存在没有已知的情况吗?

For that matter, I assume from the widespread notion (even to the example in the standard) that you can get the number of elements of an array with sizeof, that this is likely to hold true everywhere anyway - are there any known situations where it isn't?

推荐答案

我认为,该标准从来没有被认为有必要明确说明数组没有填充,这是很简单的,因为绝对没有理由这种填充在任何实现上都可能有用.

I believe it was never considered necessary for the standard to actually spell out that arrays don't have padding, for the simple reason that there is absolutely no reason why such padding might ever be useful on any implementation.

也就是说,我相信通过==运算符的描述,该标准禁止这种填充.

That said, I do believe the standard forbids such padding, through the description of the == operator.

6.5.9平等运营商

语义

6当且仅当[...]或一个为指针时,两个指针比较相等 指向一个数组对象的末尾,另一个指向另一个数组对象的开始的指针,该指针恰好紧随地址空间中的第一个数组对象.

6 Two pointers compare equal if and only if [...] or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.

给予

int array[2][2];

表达式&array[0][2]指向的指针是第一个数组子对象末尾的指针. &array[1][0]是指向第二个数组子对象的指针,该对象紧随内存中的第一个数组.这些指针需要比较相等.如果int[2]具有尾随填充,如果sizeof(int[2]) > 2 * sizeof(int),我无法想象任何实现如何使两个指针相等.

the expression &array[0][2] points is a pointer one past the end of the first array subobject. &array[1][0] is a pointer to the second array subobject, which immediately follows the first array in memory. These pointers are required to compare equal. If int[2] had trailing padding, if sizeof(int[2]) > 2 * sizeof(int), I cannot imagine how any implementation could make the two pointers compare as equal.

这篇关于数组可以有尾随填充吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆