简体   繁体   English

C结构中的数组是否对齐?

[英]C Are arrays in structs aligned?

struct {
    uint8_t foo;
    uint8_t bar;
    uint8_t baz;
    uint8_t foos[252];
    uint8_t somethingOrOther;
} A;

struct {
    uint8_t foo;
    uint8_t bar;
    uint8_t baz;
    uint8_t somethingOrOther;
    uint8_t foos[252];
} B;

Does it matter that I've put foos on byte 3 in the first example, vs on byte 4 in B? 在第一个示例中将foos放在字节3上,而在B的字节4上放置foos是否重要?

Does an array in C have to start aligned? C中的数组是否必须开始对齐?

Is the size of this struct 256 bytes exactly? 这个结构的大小是否精确为256个字节?

Given that the data type is uint8_t (equivalent to unsigned char ), there is no need for padding in the structure, regardless of how it is ordered. 假定数据类型为uint8_t (与unsigned char等效),则无需对结构进行填充,无论其顺序如何。 So, you can reasonably assume in this case that every compiler will make that structure into 256 bytes, regardless of the order of the elements. 因此,在这种情况下,您可以合理地假设,每个编译器都将使该结构变成256个字节,而与元素的顺序无关。

If there were data elements of different sizes, then you might well get padding added and the size of the structure might vary depending on the order of the elements. 如果数据元素的大小不同,那么您很可能会添加填充,结构的大小可能会根据元素的顺序而有所不同。

As the good book says (C11 section 6.7.2.1 paragraph 14): 好书所述 (C11第6.7.2.1节第14段):

Each non-bit-field member of a structure or union object is aligned in an implementation- defined manner appropriate to its type... There may be unnamed padding within a structure object 结构或联合对象的每个非位字段成员都以适合于其类型的实现定义的方式对齐...结构对象内可能存在未命名的填充

You didn't "put foos on byte 3" - apart from the fact that the first element is always on byte 0, you have no real control over what byte an element will be put on. 您没有“将foos放在字节3上”-除了第一个元素始终位于字节0上的事实之外,您无法真正控制将元素放在哪个字节上。 The compiler can give each field a full machine word or more if it thinks that will provide the most efficient accesses. 如果编译器认为可以提供最有效的访问,则可以为每个字段提供完整的机器字,甚至更多。 If so, it will allocate "padding" bytes in between - unused space. 如果是这样,它将在这两个未分配空间之间分配“填充”字节。

Note that this only applies to structs; 注意,这仅适用于结构。 arrays themselves do not add any padding bytes (if they did, the pointer arithmetic/indexing rule wouldn't work), so you can be sure that the size of foos itself is exactly the declared size, and know the exact alignment of each numbered element. 数组本身不添加任何填充字节(如果这样做,则指针算术/索引规则将不起作用),因此您可以确定foos本身的大小恰好是声明的大小,并且知道每个编号的确切对齐方式元件。

No, it doesn't matter. 不,没关系。

Pretty much every compiler out there will align struct fields to a natural boundary appropriate for the target architecture, by inserting hidden "padding bytes" between fields where necessary. 几乎所有在那里的编译器都可以通过在必要时在字段之间插入隐藏的“填充字节”来将struct字段与适合目标体系结构的自然边界对齐。

Specifically, since you're using only uint8_t , there will be no padding bytes inserted - every field already falls on a naturally-aligned boundary. 具体来说,由于仅使用uint8_t ,因此不会插入填充字节-每个字段都已经落在自然对齐的边界上。 (Everything is a multiple of one.) (一切都是一个的倍数。)

Both of the struct s you've shown are exactly 256 bytes in size. 您显示的两个struct的大小都恰好为256个字节。 You can confirm this like so: 您可以这样确认:

int main(void)
{
    printf("sizeof(struct A)=%zu \n", sizeof(struct A));
    printf("sizeof(struct B)=%zu \n", sizeof(struct B));
}

You can prevent this padding from being added by "packing" the structure: 您可以通过“打包”结构来防止添加此填充:

Do note that doing this on a structure with unaligned members can have a serious impact on the performance of your program. 请注意,在成员不对齐的结构上执行此操作会严重影响程序的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM