c - C中的预处理器指令#pragma pack

标签 c c-preprocessor pragma

这个问题在这里已经有了答案:





#pragma pack effect

(11 个回答)


4年前关闭。




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

最佳答案

一般情况下,#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 等。这些都不是真正的有效值。根据文档,

The n value below always is required to be a small power of two and specifies the new alignment in bytes



所以只有像 2、4 或 8 这样的值才有效。即使您可以使用任何整数(小数和负数没有意义),这也是不明智的。这是因为对齐两个边界的幂会加速内存访问。

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

关于c - C中的预处理器指令#pragma pack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45803016/

相关文章:

ios - 用于 'if not' 的 Objective-C 预处理器指令

c++ - 在 GCC 中,如何(暂时)抑制来自 "#pragma message"的消息

c - 如何使用 CX_LIMITED_RANGE 开/关

每 60 毫秒在 c 中创建一个文件来保存位图图像

c - 调用编译为 dylib 的 Rust 库的 Swift 程序的性能影响?

Python C接口(interface),不同模块共享静态变量?

c - 使用 isspace 和 getchar() 忽略空格

c++ - 数组初始化宏

c++ - 在 C++ 中定义短函数名称别名的最安全方法是什么?

c++ - 既然其他可滥用但有用的特性已经标准化,为什么不#pragma once呢?