对于大多数 C 编译器,可以在结构上指定编译器属性,这些属性定义该结构的成员在内存中的对齐方式。例如:
typedef struct{
char a;
char b;
} __attribute__((aligned(2))) TwoChars;
如果 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;
这最终在内存中看起来像什么? } __attribute__((aligned(2))) TwoChars
怎么样?
最佳答案
注意:这是一个非标准的特定于编译器的扩展。我在回答中提到的内容可能适用于 GCC 和 Clang,我认为这就是您所说的“大多数 C 编译器”。
one can specify compiler attributes on a struct that define how the members of that struct are aligned in memory
不,这不是 __attribute__((aligned(...)))
的工作方式。 aligned
属性仅适用于结构本身,不适用于其字段。见亲documentation page .
如果你想控制结构字段的对齐方式,你将不得不使用它们的属性。
这个:
struct {
char a;
char b;
} __attribute__((aligned(8))) foo = { 1, 2 };
将编译成类似的东西:
foo:
.byte 1
.byte 2
.zero 6
同时:
struct {
char a __attribute__((aligned(2)));
char b __attribute__((aligned(2)));
} bar = { 1, 2 };
会做你想做的事:
bar:
.byte 1
.zero 1
.byte 2
.zero 1
因此:
is this property inherited by struct members?
没有。对齐不是由结构成员继承的东西。
一件有趣的事情是,packed
属性是否由应用它的结构内的嵌套结构的成员继承,因为 packed
专门用于由结构成员继承。文档没有明确说明是否是这种情况,但我们可以很容易地检查这一点。
以下代码:
struct foo {
char a;
int b;
char c;
};
struct bar {
struct foo d;
char e;
int f;
} __attribute__((packed));
struct bar x = {{101, 102, 103}, 104, 105};
编译为:
x:
.byte 101
.zero 3
.long 102
.byte 103
.zero 3
.byte 104
.long 105
从上面我们可以看出,packed
只适用于bar
的成员,不会被foo
的成员继承,而将 __attribute__((packed))
添加到 foo
会产生以下内容:
x:
.byte 101
.long 102
.byte 103
.byte 104
.long 105
如果您想知道,这也适用于在其他结构中定义的结构:
struct bar {
struct {
char a;
int b;
char c;
} d;
char e;
int c;
} __attribute__((packed));
struct bar x = {{101, 102, 103}, 104, 105};
产生:
x:
.byte 101
.zero 3
.long 102
.byte 103
.zero 3
.byte 104
.long 105
而将 __attribute__((packed))
添加到 d
会产生:
x:
.byte 101
.long 102
.byte 103
.byte 104
.long 105
关于c - C 结构成员是否继承编译器属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64653605/