Simple analysis of C++ byte alignment is easy to ignore two problems

  • 2020-04-02 01:11:53
  • OfStack

Here are two issues that have been overlooked in development:
1. Byte alignment of Union (Union)
First look at the code:
# pragma pack (4)
Struct com
{
  The union
  {
  Double dTest;
  Int nTest;
  Char szTest [14].
  };
  Char chTest1;
  Char chTest2;
};
# pragma pack ()
 
Sizeof (struct com) =?
In GCC 4.1 and vc 2005, the answer is 20.
Debugging the memory layout of the structure, you find that the union itself adds a 2-byte padding to keep the union's own 4-byte alignment.
That is, the union in memory becomes:
The union
{
Double dTest;
Int nTest;
Char szTest [14].
Byte Padding1 [2].
};
So the union becomes 16 bytes, plus 2 char bytes, and in order to keep the struct's own bytes aligned, two more bytes are filled at the end of the struct.
The memory layout of the final structure looks like this:
# pragma pack (4)
Struct com
{
The union
{
Double dTest;
Int nTest;
Char szTest [14].
Byte Padding1 [2].
};
Char chTest1;
Char chTest2;
Byte Padding2 [2].
};
# pragma pack ()
 
2. Differences in default byte alignment in different compiler environments
For those of you who are doing platform porting, it's best to try it out for yourself first if you have an uncertain byte alignment problem. Don't take it for granted:
(1) under Win32, VC compiler default 8 byte alignment, and support 1, 2, 4, 8, 16 five kinds of alignment.
(2) under Linux 32, GCC 4.1 default 4 byte alignment, support 1, 2, 4 alignment. So the structure
Even in the case of 8-byte variables like double and long long, they are still aligned by 4 bytes. Even if I set #pragma pack of 8
(3) android 4.0, the NDK compilation environment of arm CPU, by default, when encountering variables of double, long long, different from PC Linux 32, it will be aligned according to 8-byte alignment.

Related articles: