C ++ 4字节对齐数据

时间:2012-08-16 08:29:27

标签: c++ memory

此问题与How to ensure a member is 4-byte aligned?

有关

示例:

struct Aligned
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

struct Test
{
    char    c;
    Aligned s;//is s.member 4 bytes aligned?
}


void f1()
{
    char    c1;
    Aligned s;//is s.member 4 bytes aligned?
    char    c2;
}

void f2()
{
    Aligned* s = new Aligned();//is s.member 4 bytes aligned?
}

请你解释一下“成员”在所有情况下是否都是4字节对齐,如果是,这是如何工作的?

编辑: 我忘记了Aligned派生自其他结构的情况:

struct Aligned : public SomeVariableSizeStruct
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

第二次编辑:我的问题是:总是第一个4字节对齐的结构成员?因为在这里提供的所有情况下,第一个变量地址可能不是4个字节对齐,3个字节填充不保证“成员”是4个字节对齐

4 个答案:

答案 0 :(得分:4)

是的,它有效。编译器需要使其工作。

每个类型都有一个编译器必须遵守的对齐方式。您已指定一个特定对象应使用4字节对齐,但每个其他对象,charintstd::string以及其他任何有自己的对齐要求。

因此编译器习惯于必须处理这个问题。

要确定Aligned所需的对齐方式,编译器基本上会遍历其所有成员(以及它的基类),以找到需要最严格对齐的成员。然后,这将成为所需的对齐方式。 Aligned也是如此。

在这种情况下,最对齐的成员是member,这需要4字节对齐。因此Aligned需要4字节对齐。

是的,无论您是在堆栈上创建Aligned作为函数局部变量,还是作为另一个类成员,还是在具有new的堆上创建一个{{1}}。

答案 1 :(得分:3)

它是如何运作的?

定义struct时,您可以定义在处理struct时如何使用内存。这意味着在定义struct时如下

struct Aligned
{
    char c;
    __attribute__((__aligned__(4))) int32_t member;
}

编译器定义了如何处理与此struct Aligned对应的内存。例如,编译器将使用具有以下布局的内存*:

bytes: |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
usage: |  c  |  X  |  X  |  X  |        member         |

X表示不使用这些字节。这称为填充

*:请注意,这适用于x86体系结构,并且可能在其他方面有所不同。但是不使用某些字节的事实是一样的。

答案 2 :(得分:1)

  

请你解释一下“成员”在所有情况下是否都是4字节对齐,如果是,这是如何工作的?

是的,确实如此。例外情况是,如果您告诉编译器打包您的结构。

它是如何工作的?编译器无形地对齐所有内容。它在成员之间添加填充/空格。这是ABI和生成装配的要求。当然,程序员仍然能够使用非自然对齐的数据。

作为优化,编译器可能会重新排序您的成员 - 在某些情况下:Can a C++ compiler re-order elements in a struct

答案 3 :(得分:0)

它有效,因为编译器必须使其工作。编译器将在内部具有类型Aligned的描述,其中包括诸如名称和sizeof之类的属性,以及对齐限制。