是否在C中定义了结构类型的对齐方式?

时间:2015-02-17 12:41:06

标签: c struct memory-alignment

我知道C结构中的成员与他们需要的任何边界对齐。

struct S {
  uint8_t ui8;
  /* invisible padding here */
  uint32_t ui32;
};

我的问题是,是否定义了struct S实例的对齐方式?

struct S my_s; 

是否定义了my_s的对齐方式?如果struct Sui32作为其第一个成员,这是否重要?

我已搜索但只找到了有关struct member alignment的信息。

3 个答案:

答案 0 :(得分:5)

是的,它会有一个对齐要求,是的,它取决于struct成员的类型。

C11草案规范说:

  

完整对象类型具有对齐要求,这些要求会产生限制   在可以分配该类型的对象的地址上。

  

可以使用a查询完整类型的对齐要求   _Alignof表达。

答案 1 :(得分:3)

答案:不在C99。在C11中是的。请参阅answer from unwind

在所有已知平台上的C99实践中,您可以确定类型的对齐方式:

#include <stddef.h> //Defines offsetof(.,.) 

#define alignmentof(TYPE) offsetof(struct { char w; TYPE v;},v)

C标准对于如何填充结构几乎没有说明,除了它没有问题,它们不能在开头填充,但可以在中间和结尾填充,并且必须在没有元素间填充的数组。

在实践中,没有人(我发现)已经提出了一个真正的平台,除了没有填充(所谓的打包)或填充最低限度以遵守底层硬件上数据类型的对齐

自然填充程序是:

  1. 将第一个成员放在开头(这是严格的要求)。
  2. 最小化填充下一个成员的对齐并插入。
  3. 对所有剩余成员重复。
  4. 最小化添加结束填充以确保sizeof的{​​{1}}是最严格对齐成员对齐的倍数。
  5. 如上所述,在实践中,如果发生填充,就会发生这种情况(就我的非正式调查而言)。

答案 2 :(得分:0)

是的......

struct S {
  uint8_t ui8;
  /* invisible padding here */
  uint32_t ui32;
};

的尺寸= 8

该结构包含一个4字节的uint32_t,因此struct将与4字节对齐

让我们说它从0x0开始 所以让我们看看

0x0 = ui8
0x1 = padding
0x2 = padding
0x3 = padding
0x4 = ui32

如果我们说我们在开始时添加一个uint32_t那么它会变成......结构看起来像

struct S {
  uint32_t ui32_2;
  uint8_t ui8;
  /* invisible padding here */
  uint32_t ui32;
};

然后

0x0 = ui32_2
0x4 = ui8
0x5 = padd
0x6 = padd
0x7 = padd
0x8 = ui32

结构使对齐等于它包含的最大尺寸成员。在这种情况下,结构将始终从地址

开始
  

地址%4 == 0