“#pragma pack”和“__attribute __((aligned))”之间的区别是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“#pragma pack”和“__attribute __((aligned))”之间的区别是什么?相关的知识,希望对你有一定的参考价值。
#pragma pack(L1_CACHE_LINE)
struct A {
//...
};
#pragma pack()
A a;
和
struct A {
//...
};
A a __attritube__((aligned(L1_CACHE_LINE)))
他们之间有什么区别?
#pragma pack(字节对齐)影响结构的每个成员,由字节对齐输入或其自然对齐边界指定,以较小者为准。
__attribute__((aligned(byte-alignment)))
影响变量的最小对齐(如果在struct中指定,则为struct字段)
我相信以下是相同的
#define L1_CACHE_LINE 2
struct A
{
u_int32_t a __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int32_t b __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int16_t c __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int16_t d __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int32_t e __attribute__ ( (aligned(L1_CACHE_LINE)) );
};
#pragma pack(L1_CACHE_LINE)
struct A
{
u_int32_t a;
u_int32_t b;
u_int16_t c;
u_int16_t d;
u_int32_t e;
};
#pragma pack()
在哪里是一个qazxsw poi将确保qazxsw poi内的qazxsw poi将与2字节对齐,但不会以相同的方式对齐另一个变量。
参考:
a __attritube__((aligned(L1_CACHE_LINE)))
u_int32_t a
struct A
是一种Microsoft语法,出于兼容性原因而一直是http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Fcompiler%2Fref%2Frnpgpack.htm。
http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/attributes-variables.html是一种特定于GCC的语法(MSVC不支持)。
以下是差异的摘要:
#pragma pack
(和变体)更简洁,在GCC语法中表示属性ported to GCC和__attribute__((aligned))
(参见下面的示例);#pragma pack
适用于插入之后放置的每个结构定义(或直到另一个packed
覆盖它),而GCCaligned
s在本地定义为一种类型;#pragma pack
不如属性细粒度:它不能仅应用于结构的少数成员。然而,在实践中,这很少是一个问题,因为您很少需要对同一结构的成员进行不同的对齐和打包设置。
以非常简洁的方式,#pragma pack
大致相当于__attribute__
:它定义了包装(用于节省内存的压缩结构)和最小对齐。因此pragxswpoi(最小对齐)在pragma上。
原则上,#pragma pack
可以使用GCC属性进行模拟,但不能相反,因为属性给出了更精细的控制。
以下是您可以在GCC上测试的示例:第一个定义使用#pragma pack(n)
,第二个定义使用属性。两种情况下的布局都是相同的。
__attribute__((packed,aligned(n)))
海湾合作委员会在这个例子上发出警告:n
。实际上,更简洁和恰当的解决方案是将#pragma pack
应用于整个结构(如@Hagai所做的那样),这是等效的1。但请注意,您不能简单地将#pragma pack
应用于整个结构:行为不等于将#include <stdio.h>
#include <stddef.h> // for offsetof()
#pragma pack(push, 4)
struct st {
char c;
double d;
short e;
};
#pragma pack(pop) // disables the effect of #pragma pack from now on
struct st2 {
char c __attribute__((packed,aligned(4)));
double d __attribute__((packed,aligned(4)));
short e __attribute__((packed,aligned(4)));
};
void main() {
printf("offsetof(struct st, d) = %zu
", offsetof(struct st, d));
printf("offsetof(struct st2, d) = %zu
", offsetof(struct st2, d));
printf("offsetof(struct st, e) = %zu
", offsetof(struct st, e));
printf("offsetof(struct st2, e) = %zu
", offsetof(struct st2, e));
}
分别应用于每个字段。
请注意,如果在同一结构定义中组合两个(pragma +属性),则算法更复杂,因为它必须遵守几个约束,这导致在(1)‘packed’ attribute ignored for field of type ‘char’
给出的对齐之间进行一些packed
/ aligned
计算, (2)成员类型的最小对齐,以及(3)在字段中声明的aligned
属性(如果有的话)。
1来自min
:
为struct和union类型指定packed属性等效于在每个结构或union成员上指定packed属性。
以上是关于“#pragma pack”和“__attribute __((aligned))”之间的区别是什么?的主要内容,如果未能解决你的问题,请参考以下文章