what kind of padding are c++ compilers allowed to perform?

Started by
7 comments, last by the_edd 16 years, 5 months ago
Hi, hopefully someone has some insight into this. I have code like this

struct Vec3 { float x, y, z };
std::vector<Vec3> vectors;
I need to pass in "vectors" into a function expecting an array of floats (this is for OpenGL). It would be sweet if I could just pass in "&vectors[0]", but I'm not sure if the compiler is allowed to pad the Vec3 struct under any circumstances, or if this is only done for structs with varying data sizes in them? I'm expecting this to work fine in practice, but I'd like to be nice and portable.
Advertisement
std::vector will never pad anything thats one of its important stipulations
The compiler may add four additional bytes at the end of your Vec3 structure if it so wishes, as the standard allows it to (as long as the fields appear in the correct order, no matter how they are separated). It could choose to do this for SIMD alignment reasons, for instance.

Check your compiler's documentation about padding flags, or simply assert that the size of the structure is equal to three times the size of a float.
yep, but is the compiler allowed to pad the Vec3 struct? By passing in &vector[0] (with some casts) to my function I'm telling the compiler to ignore the fact that the std::vector is full of structs instead of plain floats.
Quote:Original post by ToohrVyk
The compiler may add four additional bytes at the end of your Vec3 structure if it so wishes, as the standard allows it to (as long as the fields appear in the correct order, no matter how they are separated). It could choose to do this for SIMD alignment reasons, for instance.

Check your compiler's documentation about padding flags, or simply assert that the size of the structure is equal to three times the size of a float.


hmm, so its either
1. be portable and write a little for/copy loop or
2. do it with a cast and add a static assert.

damn... I have to compile this with 3 different compilers, so I guess its nr 1.

Edit: Thanks for the quick replies btw
Quote:Original post by rollo
yep, but is the compiler allowed to pad the Vec3 struct?

Yes, it is. In practice, compilers will never pad the fronts of structures; however, they may pad the ends, and even the middles. x86 compilers have little reason to pad beyond 32 bits, but it's not possible to guarantee that it won't happen. Instead, you should disable padding for the structure explicitly, using the compiler-specific methods (under MSVC it's #pragma pack).
ugh... I'd rather not resort to compiler specific pragmas unless there are exceptional circumstances, and I don't think this code is going to be showing up in the profiler any time soon, so I'll do the slower manual copy instead. I'll keep it in mind if it should happen to turn up though.
You don't necessarily need pragmas to specify packing. Some compilers can use command line options to indicate padding. For example, with MSVC the /Zp family of switches can be used to control structure padding.
Although it isn't a way to affect padding, it does check that none is added:

struct Vec3{~Vec3();float x, y, z;};Vec3::~Vec3() { BOOST_STATIC_ASSERT(sizeof(Vec3) == 3 * sizeof(float)); }


I have code like this in my maths library. I haven't had an assert on x86 or PPC (G5) for any of a number of compilers, using a variety of build flags.

This topic is closed to new replies.

Advertisement