首页 文章

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

提问于
浏览
3

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

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

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

struct S my_s;

是否定义了 my_s 的对齐方式?是否 struct S 作为其第一个成员 ui32 是否重要?

我搜索过但只找到了关于struct member alignment的信息 .

3 回答

  • 3

    Answer: 不在C99 . 在C11中是的 . 请参阅answer from unwind .

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

    #include <stddef.h> //Defines offsetof(.,.) 
    
    #define alignmentof(TYPE) offsetof(struct { char w; TYPE v;},v)
    

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

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

    自然填充例程是:

    • 将第一个成员放在开头(这是严格的要求) .

    • 最小填充到下一个成员的对齐并插入 .

    • 对所有剩余成员重复 .

    • 最小化添加结束填充以确保 structsizeof 是最严格对齐的成员的对齐的倍数 .

    如上所述,在实践中,如果发生填充,则会发生这种情况(就我的非正式调查所发现的而言) .

  • 5

    是的,它将具有对齐要求,是的,它将取决于 struct 的成员的类型 .

    C11规范草案说:

    完整对象类型具有对齐要求,这些要求限制了可以分配该类型对象的地址 .

    和:

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

  • 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

相关问题