【问题标题】:Gaps in aligned struct in CC中对齐结构的间隙
【发布时间】:2014-11-02 16:20:26
【问题描述】:

我有一个包含不同类型成员的庞大结构。我知道成员是根据他们的类型对齐的。
有没有办法弄清楚差距在哪里?
我的意思是我很想知道编译器在哪些成员之间插入了一个间隙(当然间隙大小是多少)。

【问题讨论】:

    标签: c struct memory-alignment


    【解决方案1】:

    它取决于平台,您可以使用 offsetof 宏通过一个小型测试程序来确定它,或者对于大多数 Unix 系统,您可以参考您架构的 System V ABI 文档。

    一般来说,额外的空间会立即插入到任何可能会不正确对齐的成员之前,而不进行任何重新排序,如果会导致数组中的下一个结构不正确对齐,则在最后插入。

    struct s { short a; int b; };
    offsetof(struct s, a) == 0
    offsetof(struct s, b) == 4 // for example
    sizeof(short) == 2
    

    间隙是 a 和 b 之间的两个字节。

    要检测结构末尾的填充,只需查看结构的大小以及最后一个元素的偏移量和大小。

    struct s2 { int a; short b; };
    offsetof(struct s2, b) == 4
    sizeof(struct s2) == 8
    

    【讨论】:

    • 请注意,并非所有类 UNIX 都遵循 System V ABI。例如,Interix 没有。
    【解决方案2】:

    使用stddef.h中定义的offsetof()

    struct my
    {
        float f ;
        double d ;
    } ;
    

    这会在 fd 之间填充:

    size_t p = offsetof(struct my , d) - ( offsetof(struct my , f) + sizeof(float) );
    

    对结构的每个成员执行此操作。

    【讨论】:

      【解决方案3】:

      如果您不想使用 offsetof 宏,您可以通过获取指针并将全部转换为 char * 来实现困难。示例:

      #include <stdio.h>
      
      struct my_struct {
          char c;
          short h;
          char c2;
          long l;
      };
      
      void display(FILE *fd) {
          struct my_struct ms;
          int delta1 = (char *)(void *) &ms.h - (char *)(void*) &ms.c;
          int gap1 = delta1 - sizeof(char);
          int delta2 = (char *)(void *) &ms.c2 - (char *)(void*) &ms.h;
          int gap2 = delta2 - sizeof(short);
          int delta3 = (char *)(void *) &ms.l - (char *)(void*) &ms.c2;
          int gap3 = delta3 - sizeof(char);
          int gap4 = sizeof(ms) -sizeof(long) - ((char *)(void *) &ms.l - (char *)(void*) &ms);
          fprintf(fd, "char to short : %d - short to char %d - char to long %d - struct to struct : %d\n",
              gap1, gap2, gap3, gap4);
      }
      int main() {
          display(stderr);
      }
      

      给:

      char to short : 1 - short to char 0 - char to long 3 - struct to struct : 0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-24
        • 2014-02-19
        • 2012-05-02
        • 2016-02-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多