小编典典

#pragma 包效果

all

我想知道是否有人可以向我解释#pragma pack预处理器语句的作用,更重要的是,为什么要使用它。

我查看了MSDN 页面,它提供了一些见解,但我希望从有经验的人那里听到更多。我以前在代码中见过它,但我似乎再也找不到在哪里了。


阅读 114

收藏
2022-05-10

共1个答案

小编典典

#pragma pack指示编译器以特定对齐方式打包结构成员。大多数编译器在声明结构时会在成员之间插入填充,以确保它们与内存中的适当地址对齐(通常是类型大小的倍数)。这避免了与访问未正确对齐的变量相关的某些架构的性能损失(或彻底错误)。例如,给定
4 字节整数和以下结构:

struct Test
{
   char AA;
   int BB;
   char CC;
};

编译器可以选择将结构放置在内存中,如下所示:

|   1   |   2   |   3   |   4   |

| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) | 
| CC(1) | pad.................. |

并且sizeof(Test)将是 4 × 3 = 12,即使它只包含 6
个字节的数据。(据我所知)最常见的用例#pragma是在使用硬件设备时,您需要确保编译器不会在数据中插入填充,并且每个成员都遵循前一个成员。使用#pragma pack(1),上面的结构将像这样布置:

|   1   |

| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |

sizeof(Test)将是 1 × 6 = 6 。

使用#pragma pack(2),上面的结构将像这样布置:

|   1   |   2   |

| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |

sizeof(Test)将是 2 × 4 = 8 。

struct 中变量的顺序也很重要。变量排序如下:

struct Test
{
   char AA;
   char CC;
   int BB;
};

#pragma pack(2),结构将像这样布置:

|   1   |   2   |

| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |

sizeOf(Test)是 3 × 2 = 6。

2022-05-10