想象一个由32位,16位和8位成员值组成的结构.成员值的排序使得每个成员都在其自然边界上.
struct Foo
{
uint32_t a;
uint16_t b;
uint8_t c;
uint8_t d;
uint32_t e;
};
Run Code Online (Sandbox Code Playgroud)
为Visual C++ 记录了成员对齐和填充规则.VC++上的sizeof(Foo)上面的结构可以预测为"12".
现在,我很确定规则是不应该对填充和对齐做出任何假设,但在实践中,其他操作系统上的其他编译器是否也做出类似的保证?
如果没有,GCC上是否有相同的"#pragma pack(1)"?
一般来说,你是正确的,这不是一个安全的假设,虽然你经常得到你期望在许多系统上的包装.packed使用gcc时,您可能希望在类型上使用该属性.
例如
struct __attribute__((packed)) Blah { /* ... */ };
Run Code Online (Sandbox Code Playgroud)
实际上,在uintXX_t存在类型的任何系统上,您将获得所需的对齐而没有填充.不要投入丑陋的gcc-isms来保证它.
编辑:详细说明使用它可能有害的原因,attribute packed或者当用作较大结构或堆栈的成员时aligned,可能导致整个结构未对齐.这肯定会损害性能,在非x86机器上,会产生更大的代码.它还意味着将指针指向结构的任何成员是无效的,因为通过指针访问该值的代码将不会意识到它可能未对齐,从而可能出错.
至于为什么它是不必要的,请记住,这attribute是特定于gcc和gcc-workalike编译器.C标准不会使对齐未定义或未指定.它是实现定义的,这意味着需要实现来进一步指定和记录它的行为方式.gcc的行为是,并且一直是,将每个结构成员对齐在其自然对齐的下一个边界上(在结构外部使用时具有相同的对齐方式,该结构必须是均匀划分类型大小的数字) .由于attribute是gcc功能,如果你使用它,你已经假设一个类似gcc的编译器,但是假设你已经拥有了你想要的对齐.
| 归档时间: |
|
| 查看次数: |
4845 次 |
| 最近记录: |