特别是在GCC上(即用GCC编译),以下两种方式有什么区别?
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&'
为什么一个错误而另一个错误呢? 内存布局至少相同吗?
您没有说明您正在使用哪个版本的GCC,但您可以在线找到相应的手册。 但是,它们在这些方面都非常兼容,因为属性和编译指示一旦定义,通常会在各版本之间保持兼容性。 我将从GCC 4.9.3的手册中引用具体的引文,目前是GCC 4系列的最新版本。 特别是,关于类型属性和结构包装编译指示的部分是相关的。
GCC手册中提到#pragma pack
和朋友:
#pragma指令用于更改随后定义的结构(除零宽度位域除外),联合和类的成员的最大对齐方式。
(重点补充)。 它说的是__attribute__((packed))
:
此属性附加到struct或union类型定义,指定放置结构或联合的每个成员(除了零宽度位字段)以最小化所需的内存。
它说的是__attribute__ ((aligned(n)))
:
此属性指定指定类型的变量的 最小对齐方式,以字节为单位。
(重点补充)。
因此,不, #pragma pack(n)
,有或没有push
,通常不等同于将__attribute__((packed, aligned(n))
附加到结构类型。前者指定受影响结构的成员在n
字节或更精细的边界上对齐。后者指定受影响结构的成员使用最小允许填充进行打包,并且对于整体结构实例的所选对齐要求必须不小于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
。
以上就是c/c++开发分享GCC上#pragma pack(push,n)/ #pragma pack(pop)和__attribute __((__ packed __,aligned(n)))之间有什么区别?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562079.html