struct member alignment - 是否可以假设没有填充

时间:2011-06-05 09:18:04

标签: c++ c linux gcc

想象一个由32位,16位和8位成员值组成的结构。成员值的排序使得每个成员都在其自然边界上。

struct Foo
{
    uint32_t a;
    uint16_t b;
    uint8_t c;
    uint8_t d;
    uint32_t e;
};

对于Visual C ++,成员对齐和填充规则是documented。 VC ++上的sizeof(Foo)上面的结构可以预测为“12”。

现在,我很确定规则是不应该对填充和对齐做出任何假设,但在实践中,其他操作系统上的其他编译器是否也做出类似的保证?

如果没有,GCC上是否有相应的“#pragma pack(1)”?

3 个答案:

答案 0 :(得分:7)

一般来说,你是正确的,这不是一个安全的假设,虽然你经常得到你期望在许多系统上的包装。使用gcc时,您可能希望在类型上使用packed属性。

E.g。

struct __attribute__((packed)) Blah { /* ... */ };

答案 1 :(得分:6)

在实际提供这些类型的系统上,很有可能工作。比方说,36位系统首先不会提供这些类型。

GCC提供属性

  

__attribute__ ((packed))

效果相似。

答案 2 :(得分:5)

实际上,在存在uintXX_t类型的任何系统上,您将获得所需的对齐而无填充。不要投入丑陋的gcc-isms来保证它。

修改:要详细说明使用attribute packedaligned可能有害的原因,可能会导致整个结构错位当用作更大结构或堆栈的成员时。这肯定会损害性能,在非x86机器上,会产生更大的代码。这也意味着它是无效来获取指向结构的任何成员的指针,因为通过指针访问该值的代码将不会意识到它可能未对齐,因此可能会出错。

至于为什么没有必要,请记住attribute特定于gcc和gcc-workalike编译器。 C标准不会使对齐未定义或未指定。它是实现定义的,这意味着需要进一步指定和记录的行为方式。 gcc的行为是,并且一直是,将每个结构成员对齐在其自然对齐的下一个边界上(在结构外部使用时具有相同的对齐方式,该结构必须是均匀划分类型大小的数字) 。由于attribute是一个gcc特性,如果你使用它,你已经假设一个类似gcc的编译器,但是假设你已经拥有了你想要的对齐。