Regarding structure padding in c++

陌路散爱 提交于 2020-12-26 04:41:41

问题


I use a datastructure in my project and in the context of a paricular structure i have a doubt about strucure padding. First Look at the strucure given below. I use Visual Studio 2008 compiler.

typedef struct tagDATA_PACK
{
   DWORD dDataLength;
   BYTE bFlags;
   BYTE bAttrib;
   BYTE bOffset;
}DATA_PACK;

Question1: How much is the size of the above structure? it shows 8 bytes. it is correct. But,

consider the modified structure given below?

typedef struct tagDATA_PACK
{
   DWORD dDataLength;
   BYTE bFlags;
}DATA_PACK;

here the size is same as the above 8byte structure. My doubt here is, where would be the compiler adding the extra 3bytes? is it after BYTE bFlags or before it?

All your answer is greatly appreciated.


回答1:


Alignment and padding for structs and classes is not specified by the standard. It's entirely down to the compiler. However, all sane compilers follow the underlying platform ABI. In your case the platform is Windows, and the Windows platform ABI is adhered to.

The padding in this case, for both structs, is after the last member. The first struct has one extra padding byte, and the second struct has three extra padding bytes.

The largest type in the struct has size 4. And that means that the overall size will be a multiple of 4. For both structs, the smallest multiple of 4 that accommodates the struct is 8.

Each data type has an alignment property. A 4 byte data type has alignment of 4. A 2 byte data type has an alignment of 2. A type with alignment of 4 is aligned when placed on a 4 byte offset from the start of the struct. A type with alignment of 2 is aligned when placed on a 2 byte offset from the start of the struct. And so on.

Members are placed at the smallest offset that respects both the order of declaration of members, and the alignment property of the members.

For an example with padding internal to the struct consider this struct

struct MyStruct
{
   char c;
   int i;
};

The alignment of c is 1, and the alignment of i is 4. So, c is placed on a 1 byte boundary, and i must be placed on a 4 byte boundary. That means that c will have offset 0, then there will be 3 padding bytes, and then i will be laid out at an offset of 4.




回答2:


Where ever the compiler wants. If it matters, you're doing something non-portable anyway, so why does it matter?




回答3:


While all the answers saying that it's up to the compiler are correct, because it is up to the compiler, the language specification places some limitations on the layout. These restrictions apply to all structures in C, "plain old data" in C++03 (which basically means only using features from C) and "standard-layout" structures in C++11 (which allows having constructor and destructor). The restrictions are:

  • (Reinterpret-)casting pointer to the structure to the type of the first member produces valid pointer to the first member (C++11 §9.2/20). Which implies there can't be padding before first member.
  • If two structures in a union have the same initial part (members of the same type in the same order) and the union is initialized via one of them, these initial members may be accessed via the other (C++11 §9.2/19). Which means the member offset may only depend on members declared before it.

The restriction to standard layout is important. Neither holds for classes that have base classes or virtual members.

Now when combined with the desire not to waste memory, this actually leaves only one practical algorithm, that is therefore used by all compilers. Which does not mean that all compilers will produce the same layout for the same input, because the sizes and alignment requirements for various primitive types differ between platforms. The algorithm is:

  • Lay out the first member at offset 0.
  • Lay out each following member at first available offset divisible by it's required alignment.
  • Round the size of the structure up to the next multiple of largest alignment of any member.
  • Alignment requirement of the structure is the largest alignment of any member.

(I am almost certain MSDN for MSVC++ describes this somewhere, but couldn't quickly find it)




回答4:


check out this:

typedef struct myTagDATA_PACK3
{
    char c;
    double d;
    int i;
}DATA_PACK3;

it shows 24 bytes. That is: double:8 bytes. int : 4 bytes + (4 bytes padding) = 8 bytes. char: 1 byte + (7 bytes padding) = 8 bytes.


Total:24 bytes.



来源:https://stackoverflow.com/questions/14684422/regarding-structure-padding-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!