gcc 编译指示包(n)与编译指示包(push,n)

oewdyzsn  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(124)

有什么区别

  1. pragma pack(n)pragma pack(push,n)
  2. #pragma pack(pop)#pragma pack()
    谁能举个例子来解释一下?什么时候应该用?
    我已经看过了,但是还在寻找更多的解释。
sdnqo3pr

sdnqo3pr1#

如果使用pushpop,则可以“堆叠”多个装箱规格。如果不使用,则可以返回默认值:

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

struct pushed_default {
    char c;
    long l;
};
#pragma pack(push, 2)
struct pushed_2 {
    char c;
    long l;
};
#pragma pack(push, 1)
struct pushed_1 {
    char c;
    long l;
};
#pragma pack(push, 4)
struct pushed_4 {
    char c;
    long l;
};
#pragma pack(pop)
struct popped_a {
    char c;
    long l;
};
#pragma pack(pop)
struct popped_b {
    char c;
    long l;
};
#pragma pack(pop)
struct popped_c {
    char c;
    long l;
};

#pragma pack(2)
struct pack_2 {
    char c;
    long l;
};
#pragma pack(1)
struct pack_1 {
    char c;
    long l;
};
#pragma pack(4)
struct pack_4 {
    char c;
    long l;
};
#pragma pack()
struct pack_a {
    char c;
    long l;
};
#pragma pack()
struct pack_b {
    char c;
    long l;
};
#pragma pack()
struct pack_c {
    char c;
    long l;
};

int main(void) {
    printf("%zu\n\n", offsetof(struct pushed_default, l));

    printf("%zu\n", offsetof(struct pushed_2, l));
    printf("%zu\n", offsetof(struct pushed_1, l));
    printf("%zu\n", offsetof(struct pushed_4, l));
    printf("%zu\n", offsetof(struct popped_a, l));
    printf("%zu\n", offsetof(struct popped_b, l));
    printf("%zu\n\n", offsetof(struct popped_c, l));

    printf("%zu\n", offsetof(struct pack_2, l));
    printf("%zu\n", offsetof(struct pack_1, l));
    printf("%zu\n", offsetof(struct pack_4, l));
    printf("%zu\n", offsetof(struct pack_a, l));
    printf("%zu\n", offsetof(struct pack_b, l));
    printf("%zu\n", offsetof(struct pack_c, l));
}

结果不言自明:

$ gcc -Wall -Wpedantic packed.c -O3 -s -o packed
$ ./packed 
8

2
1
4
1
2
8

2
1
4
8
8
8

您可以随时使用pushpop。尤其是您可以使用这些指令来使用#include头文件,而不必担心破坏其他包调整。
这是documentation的相关部分:

  1. #pragma pack(push[,n])会将目前的对齐设定推入内部堆栈,然后选择性地设定新的对齐。
  2. #pragma pack(pop)将对齐设置恢复为保存在内部堆栈顶部的值(并删除该堆栈项)。注意,#pragma pack([n])不影响该内部堆栈;因此,可以使x1M8 N1 X跟随多个x1M9 N1 X示例,并由单个x1M10 N1 X最终确定。
    不幸的是,最大推送次数没有记录。但是,在实践中,您将无法达到该值。

相关问题