Home > Enterprise >  64-bit compiler struct padding with 32-bit arguments
64-bit compiler struct padding with 32-bit arguments

Time:02-02

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:

   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

CodePudding user response:

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.

  •  Tags:  
  • Related