Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

64-bit compiler struct padding with 32-bit arguments

I’ve been trying to understand how 64-bit compiler enforces struct alignment, and I can’t understand why there is no padding in case a struct has only 32-bit arguments.

I would expect to have padding even in that case as 64-bit CPUs access memory using 64-bit pointers, don’t they?

   typedef struct {
       uint32_t a1;
       uint32_t a2;
       uint32_t a3;
   }tHeader;

  typedef struct{
      tHeader header;
      uint32_t data1;
      uint32_t data2;
  }tPacket1;



0               7   bytes
+-------+-------+
|  a1      a2   |
+-------+-------+
+-------+-------+
|  a3     data1 |       
+-------+-------+
+-------+-------+
| data2         |      <---- Why no padding here?
+-------+-------+
20 bytes.

Padding example when 64-bit argument is present:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

   typedef struct {
       uint32_t a1;
       uint32_t a2;
       uint32_t a3;
       uint64_t a4;
   }tHeader;

  typedef struct{
      tHeader header;
      uint32_t data;
  }tPacket1;



0               7   bytes
+-------+-------+
|  a1      a2   |
+-------+-------+
+-------+-------+
|  a3    PADDING|       
+-------+-------+
+-------+-------+
|       a4      |
+-------+-------+
+-------+-------+
| data   PADDING|       <---- Why padding here?
+-------+-------+
Total: 8 * 4 = 32 bytes.

Tested with:

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

>Solution :

No padding is needed in the first case because all the members have 4-byte alignment. So if you have two consecutive structures, it can be laid out like:

0               7   bytes
+-------+-------+
|  a1      a2   |
+-------+-------+
+-------+-------+
|  a3     data1 |       
+-------+-------+
+-------+-------+
| data2    a1   |
+-------+-------+
+-------+-------+
|  a2      a3   |
+-------+-------+
+-------+-------+
| data1   data2 |       
+-------+-------+

But that won’t work in the second example because a4 needs 8-byte alignment. If it omitted the padding at the end, you’d have this:

0               7   bytes
+-------+-------+
|  a1      a2   |
+-------+-------+
+-------+-------+
|  a3    PADDING|       
+-------+-------+
+-------+-------+
|       a4      |
+-------+-------+
+-------+-------+
| data     a1|      
+-------+-------+
+-------+-------+
|  a2      a3   |
+-------+-------+
+-------+-------+
|PADDING   a4   |       
+-------+-------+
+-------+-------+
| a4      data  |
+-------+-------+

But splitting the second a4 like that is not permitted.

You could use the packed attribute to force it. Then the 64-bit element would be accessed using multiple 32-bit instructions. This would also obviate the padding between a3 and a4.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading