仅带字符字段的c结构的大小

仅带字符字段的c结构的大小,c,struct,memory-alignment,struct-member-alignment,C,Struct,Memory Alignment,Struct Member Alignment,我了解填充的工作原理。我知道路线是什么。对我来说奇怪的是,为什么只有char字段的结构的大小没有对齐到4个字节(结尾填充)?我怀疑规范并不能保证这一点,所以编译器不会这样做。如果是这样的话,我可以参考一下这样的规则吗?我主要对x86和x86-64体系结构感兴趣 例如: struct foo { char field1; char field2; char field3; } foo2; int main(void) { printf("sizeof=%lu\n"

我了解填充的工作原理。我知道路线是什么。对我来说奇怪的是,为什么只有char字段的结构的大小没有对齐到4个字节(结尾填充)?我怀疑规范并不能保证这一点,所以编译器不会这样做。如果是这样的话,我可以参考一下这样的规则吗?我主要对x86和x86-64体系结构感兴趣

例如:

struct foo {
    char field1;
    char field2;
    char field3;
} foo2;

int main(void)
{
    printf("sizeof=%lu\n", sizeof foo2);
}

输出:
sizeof=3

结构的对齐方式必须确保其所有字段也正确对齐(特别是如果它们是数组的一部分)

因为这里的所有字段都有一个对齐要求,这也是结构本身的对齐要求

换句话说,如果将其中两个结构相邻放置,则两个结构中的任何字段都不会违反对齐要求

与之相比:

struct moreComplexCase {
    char char1WithAlignment1;
    // 3 byte gap to align below item.
    unint32_t uintWithAlignment4;
    char char2WithAlignment1;
    // 3 byte gap to align structure itself.
}
您将在那里看到两个填充部分。第一个是确保
uint32\u t
正确对齐(您还应该能够看到结构对齐也需要四个,以便
uint32\u t
与给定的填充正确对齐)

最后一个填充是确保数组的第二个元素(以及所有后续元素)也将正确对齐


C标准本身并不规定对齐是什么,只是可能存在对齐。例如,早期的x86芯片(可能是当前的)可以很好地处理未对齐的数据(或者可能会慢一点),而其他体系结构(例如早期的ARM芯片)在尝试这样做时只会崩溃或引发故障。

您的填充在哪里?您有3个
char
s,因此您有3个字节。结构不需要在末尾填充,因为大多数系统上的字节(
char
在大多数平台上是8位字节)可以在奇数和偶数地址上访问,即它们的对齐方式是
1
。在ARM OABI(apcs gnu)中,这将是4字节对齐的。(别问我为什么,那个ABI没什么意义)@M.M那很有趣。有这种规格的文件吗?我只能找到一些更新的。@hencew5,没有规范。相反,ABI只是“gcc所做的”。非常需要新的规范(EABI)。好的,我想我已经得到了。问题是,我认为最好是在可按内存地址的本机大小划分的地址上访问此结构(x86上为4字节,x86-64上为8字节)。但是,您知道这是否适用于任何其他体系结构,如ARM或PowerPC?它是完全可移植的吗?相当多的CPU支持从任何地址加载单个字节。主要发生的是,整个缓存线都被填满了,所以从那时起,将字节放入寄存器就相对容易了。在没有的机器上,事情变得有趣起来,比如Prime大型机(古代历史)。它们有16位字,这是可以加载到寄存器中的最小数据单元,“而如果你尝试这样做,其他体系结构会像廉价西装一样折叠”。这是否意味着未对齐的访问在此类体系结构上不需要太多或任何开销?我不是以英语为母语的人,所以我很困惑“折叠”在这种情况下是什么意思:)对不起,@hencew5,会让它变得不那么地域性:-)“像廉价西装一样折叠”意味着它会严重坍塌。