这是该程序输出的正确解释吗?

时间:2013-06-20 16:12:22

标签: c structure

#include<stdio.h>

int main()
{
    struct test
    {
        char c;
        int y;
        float r;
        double d;
    } t1; 
    printf("%d\n",sizeof(t1));
    return 0;
}   

输出: 24我的gcc 4.3.2 Ubuntu 12.04

输出:Ideone Link for Running Code

上的20

我的解释: 我认为24是对的。如果我错了,请纠正我?

  1. 第一块将被Char'c'占用。 1个字节为自己,后跟3个字节的填充。
  2. 第二个块将被整数'y'占用。 (在这种情况下,不需要填充,因为整数是4字节。因此它将完全填充块。)
  3. 第3个大块将被浮动'r'占用。 (不需要填充,因为float也是4字节)。
  4. 现在将填充4个字节的下一个块,因为接下来是双倍的。和存储地址必须是该数据类型的多个大小。
  5. 和接下来的2个4字节的块将被双变量占用。
  6. 因此Size = 1(char) + 3(Padded in Char case) + 4(int) + 4(float) + 4(padded for Double) + 8(double) = 24

    清晰度:

    由于Chunks采用4字节采集。所以每个地址都是4的倍数。 对于double,Next地址必须是1012.但它不是8的倍数。所以填充它!并从1016年开始 memory layout 我的问题 - 24是正确的,我的解释是正确的还是我的解释是错的,请解释一下?

2 个答案:

答案 0 :(得分:5)

在特定编译器输出具有该结构的特定布局的二进制文件的意义上,您的解释是正确的。如果您已正确预测输出,那么您的预测显然正确,以便在此特定时间进行特定设置

但结构的大小不是,无论如何,在C中严格定义。在这个主题中唯一定义的是结构成员的顺序和第一个成员的偏移量。填充,因此结构的总大小未定义,并且它作为编译器的决定而留下。显然,编译器填充结构的主要原因是通过基于各个类型的成员的正确对齐来提高性能(正如您正确指出的那样)。但是(这在这里很重要)编译器根据目标架构选择最有效的填充。例如,如果体系结构具有128位int,则可以想象结构的大小将如何根本不同。

所以,如果涉及到C语言的定义方面(或者除了你所描述的以外的任何设置)你的预测将毫无根据。它自然会匹配一些设置,但只是偶然。

答案 1 :(得分:1)

Padding用于使用指令优化。 C语言没有指定任何有关填充的内容。唯一的问题是,如果loadq(8字节日期)没有从8字节地址边界开始,则会发生H / W陷阱。因此,对于此示例数据结构,我当然可以编写一个没有任何填充的编译器。唯一的问题是我需要使用loadb / storb指令而不是看起来很愚蠢的loadl / storl / loadq / storq指令。如果Ideone使用loadl / storl而不是loadq / storq,则20字节大小正常,并且不需要float和double之间的填充。

顺便说一下,我有一种在结构中按顺序声明8byte,4byte,2byte,1byte数据的做法,并且可能是每个可能的......