您没有说明您使用的是哪个版本的 GCC,但您可以找到相应的手册 on-line。但是,它们在这些方面都非常兼容,因为属性和 pragma 的行为一旦定义,通常会跨版本维护以实现兼容性。我将从 GCC 4.9.3 的手册中引用具体的引文,目前是 GCC 4 系列的最新可用版本。特别是 type attributes 和 structure-packing pragmas 上的部分是相关的。
GCC 手册中提到 #pragma pack 和朋友:
#pragma 指令可更改随后定义的结构(零宽度位字段除外)、联合和类的成员的最大对齐方式。
(强调添加)。它说__attribute__((packed)):
附加到结构或联合类型定义的此属性指定结构或联合的每个成员(除了零宽度位字段)的放置以最小化所需的内存。
上面写着__attribute__ ((aligned(n))):
此属性指定指定类型的变量的最小对齐方式,以字节为单位。
(强调)。
因此,不,#pragma pack(n),有或没有push,通常与将__attribute__((packed, aligned(n)) 附加到结构类型的含义不同。前者指定受影响结构的成员在n-byte 或更精细的边界上对齐。后者指定受影响结构的成员使用最小允许填充填充,并且为整个结构实例选择的对齐要求必须不小于n。它们不仅不一样,甚至不是很相似。
您应该发现#pragma pack(1) 影响结构定义对实例布局的影响与将__attribute__((packed)) 附加到该结构的定义相同。然而,即使他们完成了相同的目标,他们也不是同一件事。两者的行为和效果都超出了 C++ 规范,GCC 完全有权在其他方面区别对待它们。
但是,如果您想使用属性来影响结构成员的对齐方式,那么您需要在逐个成员的基础上应用至少一些属性。比如……
struct foo1 {
char a;
int b __attribute__((aligned(n)));
} __attribute__((packed));
...可能与...具有相同的效果
#pragma pack(push, n)
struct foo2 {
char a;
int b;
};
#pragma pack(pop)
...,取决于n。