注:这是一个非标准的编译器特定扩展。我在回答中提到的内容可能适用于GCC和Clang,我认为这就是你所谓的“大多数C编译器”。
可以在结构体上指定编译器属性,定义该结构体成员在内存中的对齐方式。
不是这样的,__attribute__((aligned(...)))
只适用于结构体本身,而不适用于其字段。请参见相关的文档页面。
如果要控制结构体字段的对齐方式,您必须在它们上面使用该属性。
这样写:
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
因此:
结构成员不会继承此属性。
有趣的是,我们需要知道是否
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
如果将d
添加__attribute__((packed))
,则会产生以下结果:
x:
.byte 101
.long 102
.byte 103
.byte 104
.long 105
TwoChars
变量,另一个具有ThreeChars
。这些应该是兼容的。但如果在第二个TU中继承了它,那么它们将不兼容。 - Eugene Sh.