预处理器指令#pragma pack in C

时间:2017-08-21 17:52:34

标签: c c-preprocessor pragma

我试图理解#pragma的使用,特别是#pragma pack()指令。当我将pragma pack设置为4.5,-5,6等时,它是如何工作的。

1 个答案:

答案 0 :(得分:2)

一般来说,#pragma pack的目的是通过控制其成员的最大对齐来控制c中结构的大小和布局。

请参阅the GCC Docs了解语法的完整说明

我首先要关注对齐方式。当程序对对齐没有要求时,结构的成员可能与基址有任何偏差。如果存在对齐,例如4,则所有成员的偏移量必须是4的倍数。

#pragma pack(4)最大对齐设置为4,而不是最小或精确对齐。我没有办法强迫最小的对齐

这是一个示例,看看对齐时的效果(我的机器上默认对齐为4)

#include <stdio.h>
#include <stddef.h>

typedef struct { 
    char  a; 
    char  b;
    long  c;
    short d;
    long  e;
} foo;

#pragma pack(push,2) //This saves the previous alignment, then lowers the maximum alignment from 4 to 2, so it will smaller (or the same size)
typedef struct {
    char  a;
    char  b;
    long  c;
    short d;
    long  e;
} bar;
#pragma pack(pop) //This reinstates the previous alignment

int main() {
    printf("a:%d b:%d c:%d d:%d e:%d\n", offsetof(foo, a), offsetof(foo, b), offsetof(foo, c), offsetof(foo, d), offsetof(foo, e));
    printf("a:%d b:%d c:%d d:%d e:%d\n", offsetof(bar, a), offsetof(bar, b), offsetof(bar, c), offsetof(bar, d), offsetof(bar, e));
}

这给出了

的输出
a:0 b:1 c:4 d:8 e:12
a:0 b:1 c:2 d:6 e:8

关于你使用#pragma pack(n)时有什么影响的问题,其中n是4.5,-1,6等,其中没有一个实际上是有效值。根据文档,

  

下面的n值始终需要是2的小幂,并以字节

指定新的对齐

因此只有像2,4或8这样的值才有效。即使你可以使用任何整数(分数和负数都没有意义),这也是不明智的。这是因为对齐两个边界的功率会加快内存访问速度。

推送和弹出功能用于保存对齐,以便您可以随意使用它们并在以后恢复它们