Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

64 bit alignment/padding for c structure?

Tags:

c

padding

64-bit

struct tag_t_ {
    u_int8_t op;
    u_int8_t num;
    u_int32_t labels[5];
};

In the above structure where will be pad bytes added by 64-bit compiler?
Is it before the first label or at the end of first label?
If the padding is at end of the first label, Will it cause any erroneous result while accessing (reading) the first label in 32 bit archs?

like image 703
user1805194 Avatar asked Feb 19 '23 14:02

user1805194


2 Answers

I'm running this in 64-bit system -- the memory map of the struct is

offset:  variable
     0:  op num     
     2:  00 00   // only 2 paddings
     4:  label0
     8:  label1
         ...
    20:  label5

sizeof(struct) == 24

// here one could fit an unsigned short between the chars and the first 32-bit integer without affecting the size of the struct.

The rule for struct padding is that any basic variable of width W, will be aligned to that width. Double as second parameter would cause 7 padding bytes after op and only 3 padding bytes after num, as labels[0] would then start at an offset divisible by 4.

There's a difference between 32/64 bit systems: 32-bit systems will still align 8-byte variables to 32-bit boundaries. 64-bit systems will align long int and double to 8-byte boundaries.

This would make it safe to use that struct in 32-bit system. If there were doubles in the struct, one could still make the structs compatible with careful planning of the variables.

like image 68
Aki Suihkonen Avatar answered Feb 21 '23 04:02

Aki Suihkonen


It depends on the compiler, there's no universal rule that can be applied and guaranteed to hold.

I'm not sure about the second half of the question, since on the 32-bit architecture the compiler will be different, of course. It's never a good idea to transfer structures directly.

Because of the padding, if you write sizeof (tag_t_) bytes to some external media on the 64-bit machine, transfer the media and and then try to read sizeof (tag_t_) on the 32-bit machine, it will fail. So don't do that. Serialize structures field-by-field, and de-serialize them the same way.

like image 20
unwind Avatar answered Feb 21 '23 02:02

unwind