此问题与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个字节对齐
答案 0 :(得分:4)
是的,它有效。编译器需要使其工作。
每个类型都有一个编译器必须遵守的对齐方式。您已指定一个特定对象应使用4字节对齐,但每个其他对象,char
,int
,std::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
之类的属性,以及对齐限制。