#pragma pack(L1_CACHE_LINE)
struct A {
//...
};
#pragma pack()
A a;
Run Code Online (Sandbox Code Playgroud)
和
struct A {
//...
};
A a __attritube__((aligned(L1_CACHE_LINE)))
Run Code Online (Sandbox Code Playgroud)
他们之间有什么区别?
Hag*_*gai 12
#pragma pack(字节对齐)影响结构的每个成员,由字节对齐输入或其自然对齐边界指定,以较小者为准.
的__attribute__((aligned(byte-alignment)))(如果该结构内指定的或结构域)影响的变量的最小对准
我相信以下是相同的
#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()
Run Code Online (Sandbox Code Playgroud)
A a __attritube__((aligned(L1_CACHE_LINE)))将确保u_int32_t a内部struct A将与2字节对齐,但不会以相同方式对齐其他变量.
参考:
ano*_*nol 10
#pragma pack是出于兼容性原因而已移植到GCC的Microsoft语法.
__attribute__((aligned)) 是GCC特定的语法(MSVC不支持).
以下是差异的摘要:
#pragma pack(和变体)是更简洁,并且表示两个属性packed和aligned在GCC语法(见下例);#pragma pack适用于插入之后放置的每个结构定义(或直到另一个#pragma pack重写它),而GCC __attribute__在本地定义为类型;#pragma pack比属性更细粒度:它不能仅应用于结构的少数成员.然而,在实践中,这很少是一个问题,因为您很少需要对同一结构的成员进行不同的对齐和打包设置.以非常简洁的方式,#pragma pack(n)大致相当于__attribute__((packed,aligned(n))):它定义了包装(用于节省内存的压缩结构)和最小对齐.因此n,pragma上的(最小对齐).
原则上,#pragma pack可以使用GCC属性进行模拟,但不能相反,因为属性给出了更精细的控制.
以下是您可以在GCC上测试的示例:第一个定义使用#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\n", offsetof(struct st, d));
printf("offsetof(struct st2, d) = %zu\n", offsetof(struct st2, d));
printf("offsetof(struct st, e) = %zu\n", offsetof(struct st, e));
printf("offsetof(struct st2, e) = %zu\n", offsetof(struct st2, e));
}
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会就此例子发出警告:‘packed’ attribute ignored for field of type ‘char’.实际上,一个更简洁和正确的解决方案是应用于packed整个结构(如@Hagai所做的),这相当于1.但请注意,您不能简单地应用于aligned整个结构:行为不等于aligned单独应用于每个字段.
请注意,如果在同一结构定义中同时组合两个(pragma +属性),则算法更复杂,因为它必须遵守几个约束,这会导致(1)对齐给出的一些min/ max计算#pragma pack,(2)成员类型的最小对齐,以及(3)aligned字段中声明的属性(如果有).
1来自GCC文件:
为struct和union类型指定packed属性等效于在每个结构或union成员上指定packed属性.