Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Struct padding
#1
Hi! I have a question.
Are structs automatically padded during compilation? I recommend you to order your fields by size or manually padding your fields like this :

Field ordering :
Code:
typedef struct
{

typedef struct
{
int x; /*!< horizontal position */
int y; /*!< vertical position */
int width; /*!< horizontal size */
int height; /*!< vertical size */
uint16_t id; /*!< unique ID */
uint16_t gid; /*!< graphic ID (tile index) */
uint16_t flags; /*!< attributes (FLAG_FLIPX, FLAG_FLIPY, FLAG_PRIORITY) */
uint8_t type; /*!< type property */
bool visible; /*!< visible property */
char name[64]; /*!< name property */
}
TLN_ObjectInfo;

Manual padding :
Code:
typedef struct
{
uint16_t id; /*!< unique ID */
uint16_t gid; /*!< graphic ID (tile index) */
uint16_t flags; /*!< attributes (FLAG_FLIPX, FLAG_FLIPY, FLAG_PRIORITY) */
uint16_t padding;
int x; /*!< horizontal position */
int y; /*!< vertical position */
int width; /*!< horizontal size */
int height; /*!< vertical size */
uint8_t type; /*!< type property */
bool visible; /*!< visible property */
char name[64]; /*!< name property */
}
TLN_ObjectInfo;
Reply
#2
Hi!

When arranging structs in C, to maximize packing it's recommended to group members by type size, starting from the biggest one down to the smallest one. On the contrary, mixing types leads to holes in memory, as the compiler puts each member on the nearest memory address that is a multiple of the member's type size. That's why ordering members by their type, from bigger to smallest, plays nice with memory boundaries.

However, I guess I decided to arrange members based on their relevance. So the id and gid members are "key fields", whereas x and y are lesser attributes. This helps when debugging because important fields appear first, albeit some tens of bytes can be wasted.

Thanks for making this observation :-)
Reply
#3
(02-07-2025, 03:27 AM)megamarc Wrote: Hi!

When arranging structs in C, to maximize packing it's recommended to group members by type size, starting from the biggest one down to the smallest one. On the contrary, mixing types leads to holes in memory, as the compiler puts each member on the nearest memory address that is a multiple of the member's type size. That's why ordering members by their type, from bigger to smallest, plays nice with memory boundaries.

However, I guess I decided to arrange members based on their relevance. So the id and gid members are "key fields", whereas x and y are lesser attributes. This helps when debugging because important fields appear first, albeit some tens of bytes can be wasted.

Thanks for making this observation :-)

You're welcome! I noticed this issue while making a binding. I don't know if it's the same behavior between ARM and x86_64 either. Quite a sensitive topic.
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)