在GCC上的#pragma pack(push,n)/#pragma pack(pop)和__attribute __((__ packed__,aligned(n)))之间有什么区别? [英] What are the differences between #pragma pack(push, n)/#pragma pack(pop) and __attribute__((__packed__, aligned(n) )) on GCC?

查看:1274
本文介绍了在GCC上的#pragma pack(push,n)/#pragma pack(pop)和__attribute __((__ packed__,aligned(n)))之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

特别是在GCC(也就是说,用GCC编译),下面两个工作方式之间的区别是什么?

On GCC specifically (that is, compiling both with GCC), what are the differences between the way the following two work?

struct foo1 {
    char a;
    int b;
} __attribute__((__packed__, aligned(n) ));

和:

#pragma pack(push, n)
struct foo2 {
    char a;
    int b;
};
#pragma pack(pop)

他们看起来行为不同

foo1 f1;
foo2 f2;

int& i1 = f1.b; // ok
int& i2 = f2.b; // cannot bind packed field 'f2.foo2::b' to 'int&'

有一个错误在一个还没有另一个?内存布局是否相同,至少?

Why is there an error in one yet not the other? Are the memory layouts the same, at least?

推荐答案

您不需要说出您使用的GCC版本,但您可以找到适当的手动在线。然而,在这些方面,它们都是非常兼容的,因为属性和编译指示的行为一旦被定义,通常在不同版本之间维持兼容性。我将从GCC 4.9.3手册中得到具体的引用,GCC 4.9.3是目前GCC 4系列的最新版本。特别是,类型属性结构包装pragmas 是相关的。

You don't say which version of GCC you're using, but you can find the appropriate manual on-line. They're all pretty compatible in these regards, however, inasmuch as the behavior of attributes and pragmas, once defined, is normally maintained across versions for compatibility. I'll draw specific quotations from the manual for GCC 4.9.3, currently the latest available version from the GCC 4 series. In particular, the sections on type attributes and on structure-packing pragmas are relevant.

GCC手册介绍了 #pragma pack


#pragma指令会更改结构的成员最大对齐方式

#pragma directives that change the maximum alignment of members of structures (other than zero-width bit-fields), unions, and classes subsequently defined.

(添加了强调)。它表示 __ attribute __((packed))

(emphasis added). It says of __attribute__((packed)):


结构或联合类型定义,指定结构或联合的每个成员(零宽度位字段除外),以最小化所需的内存。

This attribute, attached to struct or union type definition, specifies that each member (other than zero-width bit-fields) of the structure or union is placed to minimize the memory required.

它表示 __ attribute__((aligned(n)))


此属性指定指定类型变量的最小值,以字节为单位。

$ b $

因此,不, #pragma pack(n) push ,通常不表示与附加 __属性__((packed,aligned(n))到结构类型,前者指定受影响结构的成员在 n - 字节或更细边界对齐,后者规定受影响结构的成员填充最小允许填充,并且整个结构的实例的所选择的对齐要求必须不小于 n

Thus, no, #pragma pack(n), with or without push, does not, in general, mean the same as attaching __attribute__((packed, aligned(n)) to the structure type. The former specifies that members of affected structures be aligned on n-byte or finer boundaries. The latter specifies that members of the affected structure be packed with the minimum permissible padding, and that the chosen alignment requirement for instances of the overall structure must be no less than n. Not only are those not the same, they're not even very similar.

你应该会发现 #pragma pack(1)影响结构定义对实例的布局具有相同的影响,而将 __ attribute __((packed))附加到该结构的定义。即使他们完成相同的目的,但是,他们不是同样的事情。两者的行为和效果在C ++规范之外,GCC完全在其在其他方面不同地对待它们的权利。

You should find that #pragma pack(1) affecting a structure definition has the same effect on the layout of instances as does attaching __attribute__((packed)) to that structure's definition. Even if they accomplish the same end, however, they are not the same thing. The behavior and effects of both are outside the C++ specification, and GCC is entirely within its rights to treat them differently in other respects.

如果你想使用属性来影响然而,您将需要在逐个成员的基础上应用至少一些属性。例如...

If you want to use attributes to influence the alignment of structure members, however, then you will need to apply at least some attributes on a member-by-member basis. For example ...

struct foo1 {
    char a;
    int b __attribute__((aligned(n)));
} __attribute__((packed));

...可能具有与...相同的效果

... might have the same effect as ...

#pragma pack(push, n)
struct foo2 {
    char a;
    int b;
};
#pragma pack(pop)

...,取决于 n

这篇关于在GCC上的#pragma pack(push,n)/#pragma pack(pop)和__attribute __((__ packed__,aligned(n)))之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆