2
struct Foo { int a; char b; }; 

Will it be guaranteed in this case that b will have an offset of sizeof(int) in the struct? Will it be guaranteed that members will be packed together as long as all alignment requirements are being met, no padding required (Not taking into account the padding at the end to align the structures size to the largest member)?

I ask this because I would like to know if simply using fwrite() or write() to save a struct to a file can cause problems if the layout of a struct is not consistent across platforms, because then each save file would be specific to the platform on which it was created.

2 Answers 2

3

There are no guarantees. If a compiler wishes to insert unnecessary padding between structure members, it can do so. (For example, it might have determined that a particular member could be handled much more efficiently were it eight-byte aligned, even though it doesn't require alignment at all.)

Portable code intended for interoperability should not fwrite structs. Aside from the potential of differences in padding, not all platforms use the same endianness, nor the same floating point representation (if that's relevant).

Sign up to request clarification or add additional context in comments.

8 Comments

So the only way to write to structs in a portable way is via individual unsigned char?
@user16217248: The way to write data in a portable way is to use a serialization protocol on one end and the matching deserialization on the other end. That adds some overhead, of course, but there are available libraries which reduce that overhead to a reasonable minimum.
Is there a 'cross platform' way to force a struct to be packed?
@user16217248: No matter how you frame this question, the answer won't change. The only guarantees that C gives you are that there is no padding at the beginning of an object and that an array of chars is contiguous. Practically nothing else about object representation is guaranteed. If you want to send a struct from one platform to another platform, use a serialization library. (Rolling your own is not recommended.)
What about fixed width (u)intN_t types?
|
2

Strictly speaking, the C standard makes no guarantees regarding padding inside of a struct, other than no padding at the beginning.

That being said, most implementations you're likely to come across tend to perform padding in a consistent manner (see The Lost Art of Structure Packing). In your particular example however there's a potential for inconsistency as an int is not necessarily the same size on all platforms.

If you used fixed width types such as int32_t and int8_t instead of int and char then you're probably OK. Adding a static_assert for the size of the struct can help enforce this.

You do however need to worry about endianness, converting each field to a known byte order before saving and back to the host byte order after reading back.

2 Comments

So for all the C standard is concerned, could the struct in the question be 1GB in size?
@user16217248 Yes, nothing in the C standard prevents an implementation from adding that kind of padding, but in practice you'll never see that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.