【问题标题】:Size of Struct in C; GCC vs Actual CalculationC中结构的大小; GCC 与实际计算
【发布时间】:2017-04-26 21:54:30
【问题描述】:

根据c_faq

typedef struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
} T;

sizeof(T) 将在 32 位 gcc 编译器上返回 16。因为对齐是 4,所以要计算,我应该这样做:3+(1)+2+(2)+4+3+(1),其中括号表示填充。 GCC 同意。

基于这个逻辑,我自己对另一个问题做了一些练习。

typedef struct{
    char buf1[9];
    unsigned short s;
    double d;
    char buf2[3];
} S;

sizeof(S) 应该在 32 位 gcc 编译器上返回 32。因为对齐是 8,所以要计算,我应该这样做:8+1+2+(5)+8+3+(5)。但是,gcc 告诉我 sizeof(S) 是 24。

我认为是优化的原因,但是在 gcc 中弄乱了 -O0 标志后,sizeof(S) 仍然是 24。

这是怎么回事?

我是用这个gcc -m32 main.c 编译的。

提前致谢!

编辑 :所以如果我理解正确的话,我的计算和GCC的计算不匹配的原因是每个编译器都有自己处理结构数据的方式。那么计算结构大小的通用方法是什么?或者更确切地说,计算结构体大小的原始方法是什么?

【问题讨论】:

  • 您的措辞很混乱:您说 GCC 将 sizeof(S) 设为 24,但随后您说“sizeof(S) 仍会导致 32”。我认为你的问题是无效的,你只是把自己弄糊涂了。
  • 公开使用offsetof 和一些简单的输出语句可能会给你一些答案。我认为S::buf1 后面的填充可能会让你大吃一惊。
  • You might be interested in this question。值得注意的是,在 x86 上,GCC 将默认对齐 double 在 4 字节边界上,而不是 8。
  • @Jieqin,一般来说,你不会手动计算结构体的大小。您依靠sizeof 来确定您需要的大小。能够预测sizeof 的结果并不重要。
  • @Jieqin:buf1 后面有 1 个字节的填充,因为s 需要在 2 个字节的边界上对齐。 shorts 通常在 2 字节边界上对齐。

标签: c struct padding


【解决方案1】:

那么计算结构体大小的通用方法是什么?或者更确切地说,计算结构体大小的原始方法是什么?

没有通用的方法。也没有真正的“原始”方式,因为 C 是在 1970 年代创建的,当时 PDP-11 还是一个东西,而 C 直到 1989 年才正式指定。它的实现已定义,并且因平台而异(我不仅仅是轻率;它确实确实在平台和实现之间有所不同(甚至编译器标志!)。

如果您的教授希望您计算结构的大小,那么他或她必须提供每种数据类型所需的对齐方式。如果他们不这样做,那么他们的问题未充分说明(并且几乎无限数量的不同答案都可以被辩护为“正确”)。

【讨论】:

    【解决方案2】:

    我编写了以下代码来检查结构中每个元素的地址。

    #include <stdio.h>
    
    typedef struct{
        char buf1[9];
        unsigned short s;
        double d;
        char buf2[3];
    } S;
    
    int  main()
    {
        S S1;
        S *Sptr = &S1;
        printf ("\n sizeof (S) is %d",sizeof(S));
        printf ("\n Buf1 --> %d",(char*) &(Sptr->buf1[0]) - (char*)Sptr);
        printf ("\n s    --> %d",(char*) &(Sptr->s) - (char*)Sptr);
        printf ("\n d    --> %d",(char*) &(Sptr->d) - (char*)Sptr);
        printf ("\n Buf2 --> %d",(char*) &(Sptr->buf2[0]) - (char*)Sptr);
        return 0;
    }
    

    我的编译器(cygwin 64 位)的结果是

    sizeof (S) is 32
    Buf1 --> 0
    s    --> 10
    d    --> 16
    Buf2 --> 24
    

    short 位于字节 10,因此它在 2 个字节边界上对齐。双精度在 16m 处并在 8 字节边界处对齐。最终的结构体也被填充到 8 个字节。

    【讨论】:

      猜你喜欢
      • 2016-03-12
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多