Soumen
Soumen

Reputation: 1078

Struct padding difference in 32 bit and 64 bit architecture with uint64_t

I have two structures as specified below. The comments specify the size of the data members and padding values that the compiler would augment.

#include <stdio.h>
#include <stdint.h>


typedef struct peer_msg_hdr
{
  char type;            /**< 1 */
                        /**< pad[3] */
  uint32_t id;          /**< 4 */
  uint64_t timestamp;   /**< 8 */
} PEER_MSG_HDR;         /**< 16 */

typedef struct peer_msg 
{
  PEER_MSG_HDR hdr;      /**< 16 */
  uint16_t listen_port;  /**< 2 */
                         /**< pad[2] */

  uint32_t num_nodes;    /**< 4 */
  uint32_t num_proc;     /**< 4 */
} PEER_MSG;


int main()
{
  printf("%lu\n", sizeof(PEER_MSG));
  return 0;
}

Now in a x86_64 host machine, first I calculate the size of PEER_MSG. It turns out to be 32. Next, if I calculate the size with -m32 option in gcc, the size is 28.

Difference between these two arise in padding after the last data member, num_proc. In case of -m32 option compilation, there is no padding. But without -m32 option, there is a padding of 4 bytes (to align the whole structure to 8 bytes, as it should be because the widest data member size is 8 bytes (uint64_t timestamp)).

My question is: with -m32 option, size of uint64_t remains 8 bytes, but the alignment of the structure PEER_MSG is of 4 bytes, which contradicts the general rule of padding (structure alignment should be equal to the alignment of its widest data member). So what is the compiler rule here for padding with -m32 option?

Upvotes: 2

Views: 4118

Answers (2)

rashok
rashok

Reputation: 13494

My question is: with -m32 option, size of uint64_t remains 8 bytes, but the alignment of the structure PEER_MSG is of 4 bytes,

  • This is exactly correct. In 32 bit system also size of uint64_t is 8 bytes. And struct alginment is done based on word size 4 bytes.

Your point of structure alignment should be equal to the alignment of its widest data member is wrong.

  • Structure alginment is based on the word size of the architecture (not the widest data member). In 32 bit architecture word size is 4 byte, where as in 64 bit architecture word size is 8 byte.

Upvotes: 2

Jay
Jay

Reputation: 24905

On a 32 bit machine, the processing word size is 4 bytes, hence the structure gets aligned according to that which why you get the size of PEER_MSG as 28 bytes. On a 64 byte system, since the processing word size will be 8 bytes, you get the size of PEER_MSG as 32 bytes.

When you specify -m32 option, the compiler is made to assume that the final executable is going to be run on 32 byte system and hence does the padding appropriately.

Upvotes: 2

Related Questions