开发者

struct member alignment - is it possible to assume no padding

Imagine a struct made up of 32-bit, 16-bit, and 8-bit member values. Where开发者_开发知识库 the ordering of member values is such that each member is on it's natural boundary.

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

Member alignment and padding rules are documented for Visual C++. sizeof(Foo) on VC++ the above struct is predictably "12".

Now, I'm pretty sure the rule is that no assumption should be made about padding and alignment, but in practice, do other compilers on other operating systems make similar guarantees?

If not, is there an equivalent of "#pragma pack(1)" on GCC?


In practice, on any system where the uintXX_t types exist, you will get the desired alignment with no padding. Don't throw in ugly gcc-isms to try to guarantee it.

Edit: To elaborate on why it may be harmful to use attribute packed or aligned, it may cause the whole struct to be misaligned when used as a member of a larger struct or on the stack. This will definitely hurt performance and, on non-x86 machines, will generate much larger code. It also means it's invalid to take a pointer to any member of the struct, since code that accesses the value through a pointer will not be aware that it could be misaligned and thus could fault.

As for why it's unnecessary, keep in mind that attribute is specific to gcc and gcc-workalike compilers. The C standard does not leave alignment undefined or unspecified. It's implementation-defined which means the implementation is required to further specify and document how it behaves. gcc's behavior is, and always has been, to align each struct member on the next boundary of its natural alignment (the same alignment it would have when used outside of a struct, which is necessarily a number that evenly divides the size of the type). Since attribute is a gcc feature, if you use it you're already assuming a gcc-like compiler, but then by assumption you have the alignment you want already.


In general you are correct that it's not a safe assumption, although you will often get the packing you expect on many systems. You may want to use the packed attribute on your types when you use gcc.

E.g.

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


On systems that actually offer those types, it is highly likely to work. On, say, a 36-bit system those types would not be available in the first place.

GCC provides an attribute
 

__attribute__ ((packed))

With similar effect.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜