什么是包的#pragma(推,N)/#编译包(POP)和__attribute __之间的差异((__ packed__,对齐(N)))在GCC? [英] What are the differences between #pragma pack(push, n)/#pragma pack(pop) and __attribute__((__packed__, aligned(n) )) on GCC?

查看:133
本文介绍了什么是包的#pragma(推,N)/#编译包(POP)和__attribute __之间的差异((__ packed__,对齐(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的版本,但你可以找到相应的手册的在线。他们都是pretty在这些方面兼容,但是,因为属性和编译指示的行为,一旦确定,通常跨版本兼容维护。我会借鉴手册具体报价为GCC 4.9.3,目前由GCC 4系列中的最新版本。特别是,在类型属性和结构装箱编译指示是相关的。

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包朋友们:

#pragma指令是改变结构(除了零宽度位字段等),工会的最大的对齐的成员的,随后定义的类。

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

(强调)。它说的__ __属性((包装))

这个属性附加到结构或联合类型定义,规定了每个成员的结构或联合的(除了零宽度位字段等)放置,以减少所需的内存。

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__((对齐(N)))

该属性指定的最小的对齐的指定类型的变量的,以字节为单位。

This attribute specifies a minimum alignment for variables of the specified type, measured in bytes.

(强调)。

因此​​,没有,的#pragma包(N),有无,不,在一般,意思是一样的附加 __属性__((包装,对齐(N))来的结构类型。受影响结构的成员 N - 字节或更细的边界。后者指定受影响的结构的成员与最小允许填充被包装,并且对于总体结构的情况下,选择的对齐要求必须不大于<小于code> 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包(1)影响的结构定义对实例的布局相同的效果确实安装 __属性__( (包装))来该结构的定义。即使它们达到同样的目的,然而,它们不是同样的事的。行为以及两者的效果是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

这篇关于什么是包的#pragma(推,N)/#编译包(POP)和__attribute __之间的差异((__ packed__,对齐(N)))在GCC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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