- 主题:Re: gcc什么编译选项会导致结构体呈现 packed 模式?
Os?
【 在 feiy 的大作中提到: 】
: gcc什么编译选项会导致结构体呈现 packed 模式?
:
: 假设有个数据结构如下
: ...................
--
FROM 222.129.51.*
这不是查查手册就有的吗
https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html
--
FROM 222.129.205.*
没有命令行指定,也没有__attribute__((packed, aligned(1))),也没有#pragma pack(1),
但是结构却是1字节对齐的,那不是灵异事件?
【 在 feiy 的大作中提到: 】
: 谢谢,再麻烦你一下直接告诉答案吧。
: 因为的确在问之前查过手册google百度,包括-fpack-struct,都没有解决。因此,在主
: 贴特地说了很多前因后果,而不是一句简单的标题问题,就是为了避免被怼一句不会查
: ...................
--
FROM 222.129.205.*
没有灵异事件,肯定是某个角落你没注意到
#pragma pack如果不pop的话,会污染到全部看得到它的地方
1、确保你记录的命令行参数是对的
2、在1的前提下,用static_assert(sizeof(tst_struct)== xxx),根据include树,挨个查pragma pack。
【 在 feiy 的大作中提到: 】
: 对,就是这个意思。
: 所以想问问是否有人遇到过,或者是不是还有其他地方容易导致这个问题。
: 而且更诡异的是,另外一个工程(也是makefile管理的),但是却是按照各自的类型对齐的。
: ...................
--
修改:z16166 FROM 222.129.205.*
FROM 222.129.205.*
对,我也是这么怀疑,我就遇到过,造成很诡异的行为。
【 在 z16166 的大作中提到: 】
: 没有灵异事件,肯定是某个角落你没注意到
:
: #pragma pack如果不pop的话,会污染到全部看得到它的地方
: ...................
--
FROM 222.129.51.*
1、gcc默认不报这个unpack无效,要加参数才行
gcc -Wall 1.cpp
1.cpp:13:0: warning: ignoring #pragma unpack [-Wunknown-pragmas]
#pragma unpack(1)
2、#pragma pack这个最好不用。如果一定要用,用的时候最好不手动写,而是封在宏里,以保证push/pop配对。
类似下面这种,其中__pragma是MSVC专有的关键字,专门为了在宏里面用而定制的。_Pragma是C99的。注意分号的位置的区分,有点ugly。
MSVC:
#define PACKED( class_to_pack ) __pragma( pack(push, 1) ) class_to_pack __pragma( pack(pop) )
PACKED(
struct tst_struct {
uint8_t a;
uint8_t b;
uint8_t c;
uint16_t d;
uint32_t e;
}
);
C99:
#define PRAGMA(X) _Pragma(#X)
#define PRAGMA_PACK_PUSH(n) PRAGMA(pack(push,n))
#define PRAGMA_PACK_POP() PRAGMA(pack(pop))
#define PACKED(class_to_pack) \
PRAGMA_PACK_PUSH(1) \
class_to_pack \
PRAGMA_PACK_POP()
PACKED(
struct tst_struct {
uint8_t a;
uint8_t b;
uint8_t c;
uint16_t d;
uint32_t e;
};
);
3、重要的结构(一般是对外接口,比如硬件映射、文件结构映射等),每个都用static_assert(sizeof(x) == y)保护一下
【 在 feiy 的大作中提到: 】
: 你们说对了,果然是头文件包含指向一个带pragma pack的头文件。
--
修改:z16166 FROM 222.129.205.*
FROM 222.129.205.*