pragma pack()在GCC编译时不接受宏参数

#pragma pack() 可以用来让结构体内的数据紧凑地组织在一起。

最近遇到一些在MSVC下适用的代码,换成GCC编译器之后就不正常的情况。

原因分析

经过查找一些资料和尝试,发现主要原因是使用GCC编译器时, #pragma pack() 中指定的对齐字节数, 不能通过宏来传递,而MSVC则可以通过宏来传递。

测试代码

定义了一个结构体A,在使用#pragma pack(2)时, A占6字节,如果不使用则占8字节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// main.c
#include <stdint.h>
#include <stdio.h>

#if USE_MACRO
#define ALIGN 2
#pragma pack(ALIGN)
#else
#pragma pack(2)
#endif
typedef struct {
uint16_t a;
uint32_t b;
} A;
#pragma pack()

int main() {
printf("sizeof A: %u\n", sizeof(A));
return 0;
}

测试结果

1
2
3
4
5
6
7
❯ gcc -o main -DUSE_MACRO=0 main.c && ./main
sizeof A: 6
❯ gcc -o main -DUSE_MACRO=1 main.c && ./main
main.c:7:14: warning: unknown action ‘ALIGN’ for ‘#pragma pack’ - ignored [-Wpragmas]
7 | #pragma pack(ALIGN)
| ^~~~~
sizeof A: 8

测试后可以发现在不使用宏定义的情况下,结果是正确的, 但是如果使用宏定义,GCC编译时也会有相应的warning提示。

另外,如果在windows上采用MSVC编译器,即使使用宏定义,结果也会是正确的。