如何解释数据类型大小及其对齐?

时间:2017-07-01 13:22:18

标签: c linux types memory-alignment

我对linux / gcc中double类型的大小/对齐有疑问。

Wikipedia上,写了:

  

双倍(8字节)将在Windows上以8字节对齐并且为4字节   在Linux上对齐(8字节,带-malign-double编译时选项)。

我理解8字节数据类型的8字节对齐方式存储在内存中。

所以,如果我们有

struct foo {
    double d1;
    double d2;
};

我知道这个结构的大小是16个字节。但是什么是对齐?

其次,我们如何用4字节对齐来显示8字节大小?

举个例子:

int a[2];

在上述情况下,a[0]将为偏移= 0,a[1]将为偏移= 32。

但是如何在Linux(4字节对齐)中放置double类型? E.g。

double d[2];

d[0]当然会在Offset = 0. d[1]处于Offset = 64,但是对齐信息表明double是4字节对齐的。也许我在这里错过了一些观点。

1 个答案:

答案 0 :(得分:1)

简短回答

对齐取决于实施和平台。对于gcc,您可以通过__alignof__ C扩展关键字(gcc 5.4.0 doc)查询对象的对齐方式,就像使用sizeof运算符查询对象的大小一样

答案很长

<强> Q1。 struct foo { double d1; double d2; }

的对齐方式是什么?

以下示例代码显示所讨论的struct的对齐方式在64位和32位平台之间有所不同。 (用gcc 5.4.0测试)

$ cat main.c
#include <stdio.h>

struct foo {
    double d1;
    double d2;
};

int main()
{
    struct foo s_foo[2];
    printf("%d\n", (int)__alignof__(struct foo));
    printf("%p\n", &s_foo[0]);
    printf("%p\n", &s_foo[1]);
}
$ gcc -m64 -o main main.c
$ ./main
8
0x7fff54213ba0
0x7fff54213bb0
$ gcc -m32 -o main main.c
$ ./main
4
0xffb5239c   # 4-byte aligned
0xffb523ac   # 4-byte aligned
$ gcc -m32 -malign-double -o main main.c
$ ./main
8
0xffb398b8
0xffb398c8

当使用struct dd编译或编译为64位时,您可以检查-malign-double是否为4位字节对齐32位,但是8字节对齐。

<强> Q2。我们如何用4字节对齐来显示8字节大小?

以下示例显示了此类行为。 double的{​​{1}}类型成员d1的大小为8个字节,但它是4字节对齐的。

struct foo