Sign in to follow this  

Portable structure packing

This topic is 3488 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, Just a quick question, is this hack for packing a structure in C++ portable?

#ifdef _MSC_VER

	#pragma pack(push)
	#pragma pack(1)

	#define PACKED

#else

	#define PACKED __attribute((packed))__

#endif

struct ThirdPartyStruct
{
	...

} PACKED;

#ifdef _MSC_VER

	#pragma pack(pop)

#endif


Maybe someone has a better idea? Thanks

Share this post


Link to post
Share on other sites
Okay so it's __attribute__((packed)) and not __attribute((packed))__.

I don't mind if it's not cross-compiler portable, I can make a note and say that it must be compiled using either X or Y, but it needs to be able to be compiled on Windows, Linux and possibly Mac OS.

Since I only develop for Windows, this is new to me.

Thanks for the reply.

Share this post


Link to post
Share on other sites
I would add an additional #ifdef __GNUC__ around the macro that uses __attribute__, and maybe add a #warning in the #else branch, just to be sure someone trying to build with compiler XYZ will know.

Other than that, it's pretty much as portable as it can be, for the two biggest common compiler suites.

Is it strictly necessary to have the exact same layout/packing, though? Unless that struct is getting dumped straight from memory into a file which should then be read from a different platform (or something similar to this), it shouldn't really matter, as long as your third party code is compiled with the same compiler. ThirdPartyStruct.foo is still ThirdPartyStruct.foo, even with a different layout. Or is that struct coming from a library which you only have in binary form? In that case, forget what I said :-)

Endianness comes to mind too, whenever someone says "portable". You don't plan to exchange structs between programs running on different architectures, do you?

Share this post


Link to post
Share on other sites
Since you're packing, and not aligning to certain boundaries, it makes me believe this isn't for SIMD.

What is this for? Hopefully not I/O (files, network)?

Share this post


Link to post
Share on other sites
No it's nothing on that scale :P

I'm simply writing some code which reads / writes uncompressed 24-bit BMP files. Unfortunately the bitmap header structures are a mix of integers and shorts, and so it gets padded with extra bytes, which prevents the image from being read by external applications.

Thanks for your help guys, I'm rating you all up.

Share this post


Link to post
Share on other sites
Another problem with C++ is member re-ordering : while C mandates the order of members of a structure, C++ implementations are free to move them around to minimize padding.

A portability zealot would advise you to read/write each field separately. extern "C" might be enough though.

Share this post


Link to post
Share on other sites

This topic is 3488 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this