繁体   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;

在第一个示例中将foos放在字节3上,而在B的字节4上放置foos是否重要?

C中的数组是否必须开始对齐?

这个结构的大小是否精确为256个字节?

假定数据类型为uint8_t (与unsigned char等效),则无需对结构进行填充,无论其顺序如何。 因此,在这种情况下,您可以合理地假设,每个编译器都将使该结构变成256个字节,而与元素的顺序无关。

如果数据元素的大小不同,那么您很可能会添加填充,结构的大小可能会根据元素的顺序而有所不同。

好书所述 (C11第6.7.2.1节第14段):

结构或联合对象的每个非位字段成员都以适合于其类型的实现定义的方式对齐...结构对象内可能存在未命名的填充

您没有“将foos放在字节3上”-除了第一个元素始终位于字节0上的事实之外,您无法真正控制将元素放在哪个字节上。 如果编译器认为可以提供最有效的访问,则可以为每个字段提供完整的机器字,甚至更多。 如果是这样,它将在这两个未分配空间之间分配“填充”字节。

注意,这仅适用于结构。 数组本身不添加任何填充字节(如果这样做,则指针算术/索引规则将不起作用),因此您可以确定foos本身的大小恰好是声明的大小,并且知道每个编号的确切对齐方式元件。

不,没关系。

几乎所有在那里的编译器都可以通过在必要时在字段之间插入隐藏的“填充字节”来将struct字段与适合目标体系结构的自然边界对齐。

具体来说,由于仅使用uint8_t ,因此不会插入填充字节-每个字段都已经落在自然对齐的边界上。 (一切都是一个的倍数。)

您显示的两个struct的大小都恰好为256个字节。 您可以这样确认:

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

您可以通过“打包”结构来防止添加此填充:

请注意,在成员不对齐的结构上执行此操作会严重影响程序的性能。

暂无
暂无

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

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