Fre*_*rey 3 c gcc struct memory-alignment
对于大多数 C 编译器,可以在结构上指定编译器属性,该属性定义该结构的成员在内存中的对齐方式。前任:
typedef struct{
char a;
char b;
} __attribute__((aligned(2))) TwoChars;
Run Code Online (Sandbox Code Playgroud)
如果char a以地址 0xA 结束(为简单起见),则char b不会在地址 0xB 处,而是在 0xC 处,因为它与 2 个字节对齐。
我的问题是:这个属性是由结构成员继承的吗?前任:
typedef struct{
char a;
char b;
} TwoChars;
typedef struct {
TwoChars tc;
char c;
} __attribute__((aligned(1))) ThreeChars;
Run Code Online (Sandbox Code Playgroud)
这在内存中最终会是什么样子?怎么样} __attribute__((aligned(2))) TwoChars?
注意:这是一个非标准的编译器特定扩展。我在回答中提到的内容可能适用于 GCC 和 Clang,我认为这就是“大多数 C 编译器”的意思。
可以在结构上指定编译器属性,该属性定义该结构的成员在内存中的对齐方式
不,这不是__attribute__((aligned(...)))工作方式。该aligned属性仅适用于结构本身,而不适用于其字段。请参阅相关文档页面。
如果要控制结构字段的对齐方式,则必须对它们使用该属性。
这个:
struct {
char a;
char b;
} __attribute__((aligned(8))) foo = { 1, 2 };
Run Code Online (Sandbox Code Playgroud)
将编译为类似:
foo:
.byte 1
.byte 2
.zero 6
Run Code Online (Sandbox Code Playgroud)
虽然这个:
foo:
.byte 1
.byte 2
.zero 6
Run Code Online (Sandbox Code Playgroud)
会做你想做的:
bar:
.byte 1
.zero 1
.byte 2
.zero 1
Run Code Online (Sandbox Code Playgroud)
所以:
这个属性是由结构成员继承的吗?
不。对齐不是结构成员继承的东西。
一个有趣的事情是,如果该packed属性被应用它的结构内的嵌套结构的成员继承,因为packed它专门由结构成员继承。文档没有明确说明是否是这种情况,但我们可以很容易地检查这一点。
以下代码:
struct {
char a __attribute__((aligned(2)));
char b __attribute__((aligned(2)));
} bar = { 1, 2 };
Run Code Online (Sandbox Code Playgroud)
编译为:
x:
.byte 101
.zero 3
.long 102
.byte 103
.zero 3
.byte 104
.long 105
Run Code Online (Sandbox Code Playgroud)
从上面我们可以看出,packed仅适用于 的成员,bar并且不会被 的成员继承foo,而添加__attribute__((packed))到foo会产生以下结果:
x:
.byte 101
.long 102
.byte 103
.byte 104
.long 105
Run Code Online (Sandbox Code Playgroud)
如果您想知道,这也适用于在其他结构中定义的结构:
struct bar {
struct {
char a;
int b;
char c;
} d;
char e;
int c;
} __attribute__((packed));
struct bar x = {{101, 102, 103}, 104, 105};
Run Code Online (Sandbox Code Playgroud)
产生:
x:
.byte 101
.zero 3
.long 102
.byte 103
.zero 3
.byte 104
.long 105
Run Code Online (Sandbox Code Playgroud)
而添加__attribute__((packed))到d产生:
x:
.byte 101
.long 102
.byte 103
.byte 104
.long 105
Run Code Online (Sandbox Code Playgroud)