#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));
}
GCC会在这个范例中发出警告:‘packed’ attribute ignored for field of type ‘char’。实际上,一个更简洁、更合适的解决方案是将packed应用于整个结构(就像@Hagai所做的那样),这是等价的1。但是,请注意,您不能简单地将aligned应用于整个结构:该行为"不“等同于将X1 M17 N1 X分别应用于每个字段。 请注意,如果将两者合并(pragma + attributes),则该算法更为复杂,因为它必须遵守几个约束,这导致在(1)由#pragma pack指定的对齐方式,(2)成员型别的最小对齐方式,以及(3)字段中宣告的aligned属性(如果有的话)。 1从GCC documentation: 为结构和联合类型指定packed属性等效于为每个结构或联合成员指定packed属性。
3条答案
按热度按时间qcuzuvrc1#
#pragma pack
是Microsoft语法,出于兼容性原因,它已被称为ported to GCC。__attribute__((aligned))
是GCC特定语法(MSVC不支持)。以下是差异摘要:
#pragma pack
(和变体)更简洁,并且在GCC语法中表示两个属性packed
和aligned
(参见下面的示例);#pragma pack
应用于放置在它被插入的位置之后的每个结构定义(或者直到另一个#pragma pack
覆盖它),而GCC__attribute__
被本地定义到类型;#pragma pack
的粒度没有属性细:它不能只应用于结构体中的几个成员。但是,实际上,这很少是个问题,因为您很少需要为同一个结构体的成员使用不同的对齐和封装设置。#pragma pack(n)
大致相当于__attribute__((packed,aligned(n)))
,非常简洁:它定义了 packing(压缩结构以节省内存)和minimal alignment。因此,编译指示上有n
(minimal alignment)。原则上,
#pragma pack
可以使用GCC属性来模拟,但不能反过来,因为属性提供了更精细的控制。下面是一个可以在GCC上测试的示例:第一个定义使用
#pragma pack
,第二个定义使用属性。两种情况下的布局相同。GCC会在这个范例中发出警告:
‘packed’ attribute ignored for field of type ‘char’
。实际上,一个更简洁、更合适的解决方案是将packed
应用于整个结构(就像@Hagai所做的那样),这是等价的1。但是,请注意,您不能简单地将aligned
应用于整个结构:该行为"不“等同于将X1 M17 N1 X分别应用于每个字段。请注意,如果将两者合并(pragma + attributes),则该算法更为复杂,因为它必须遵守几个约束,这导致在(1)由
#pragma pack
指定的对齐方式,(2)成员型别的最小对齐方式,以及(3)字段中宣告的aligned
属性(如果有的话)。1从GCC documentation:
为结构和联合类型指定packed属性等效于为每个结构或联合成员指定packed属性。
odopli942#
pragma pack(字节对齐)会影响结构的每个成员,如字节对齐输入所指定,或在其自然对齐边界上,以较小者为准。
__attribute__((aligned(byte-alignment)))
影响变量(或结构字段,如果在结构中指定)的最小对齐我认为以下是等效的
其中是A
a __attritube__((aligned(L1_CACHE_LINE)))
将确保struct A
内的u_int32_t a
将与2个字节对齐,但不会以相同方式对齐其他变量。参考编号:
aiazj4mn3#
我没能得到和其他答案一样的结果。答案也许比目前所说的更微妙。
这是在gcc(Ubuntu 11.2.0- 19 ubuntu 1)11.2.0中实现的。