【问题标题】:Alignment of byte array in struct结构中字节数组的对齐
【发布时间】:2014-01-31 22:39:27
【问题描述】:

我想知道标准对如何对齐和分配以下结构有何规定:

struct A {
   uint8_t b[16];
};

我可以期望A 的大小为 16 字节,在数组中的 16 字节边界上对齐(@9​​87654323@ 的大小等于16*n,例如没有填充)和@的地址987654325@ 将是b 的第一个元素?

为了缩小范围,我关注的平台是 x86/x64、ARM M、R、A 和 A50。

编辑:澄清 - “对齐”我的意思是编译器将如何对齐堆栈上数组中的对象,例如每个下一个元素是否会相隔 16 个字节,自然我不希望 malloc 与平台默认边界以外的任何内容对齐。

编辑 2:阅读答案后,我想问,我可以期望特定于平台的显式对齐内在函数在多大程度上起作用?

【问题讨论】:

  • 结构A的地址总是它的第一个元素的地址。
  • 是的,除了 16 字节对齐之外的所有内容,这是不保证的。它只是您平台的最小对齐方式,通常 32 位平台为 4 个字节,64 位平台为 8 个字节。
  • 很有趣,看看你在感兴趣的平台上获得了什么大小struct xx { uint8_t c; struct A d; uint8_t e; struct A f; uint8_t g[14];}。 48还是别的什么?

标签: c arrays struct alignment sizeof


【解决方案1】:

结构的大小将至少为 16。在正常的 C 实现中它将是 16,但我不认为 C 标准要求这样做,没有情有可原的情况,例如用户的特殊要求。例如,如果用户使用 GCC 的扩展来指定结构必须有 32 字节的对齐,那么结构必须被填充到 32 字节。

不能期望结构的对齐要求为 16。其成员的对齐要求均不大于 1,并且 C 标准不要求结构的对齐要求大于其成员。我不认为 C 标准要求结构的对齐要求不大于满足其成员要求所需的最小值,因此 C 实现可能会给结构 16 对齐。我是不知道没有用户特殊要求的 C 实现。

从技术上讲,指向 struct 的指针不能与指向 b 的第一个元素的指针相同,因为前者是指向 struct 的指针,而后者是指向 char 的指针。但是,当指向结构的指针转换为指向uint8_t [16] 的指针时,它将与b 的地址相同(将比较等于)。

在我熟悉的每个 C 实现中,当指向结构的指针或指向数组的指针进一步转换为指向 uint8_t 的指针时,它将与(将比较等于)指针相同到b 的第一个元素。但是,我没有看到 C 标准可以保证这一点。当然,结构体或数组的开头没有填充,所以我们知道结构体的“地址”与数组的“地址”和第一个元素的“地址”相同,但事实并非如此就像保证转换不同类型的指针会产生正确的值一样。

【讨论】:

  • 这就是为什么我没有说指针而是地址,例如好像转换为void *
  • @ddriver:我知道您使用了“地址”一词,但 C 仅定义了指针的行为。本质上,地址仅作为指针的值存在于 C 模型中。检查指针仅限于您可以对它们执行的操作:将它们与其他指针进行比较,在界限内进行一些算术运算,比较它们。很可能表示指向结构的指针的字节与表示指向uint8_t 的指针的字节不同。但是,当一个转换为另一个时,如我的回答中所述,它们将比较相等。
  • 好吧,有点“附带问题”,GCC 早就有对齐内在函数,考虑到 ARM M0 的工具链是 4.8 版,我可以期望对齐内在函数在这样一个高度嵌入式的平台上工作?
  • @ddriver:ARM’s compiler appears to support the aligned attribute.。我没有检查该文档所涵盖的工具链版本,但我认为您可能会发现它适用于这方面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 2012-07-18
  • 2017-03-29
  • 2013-06-12
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多