Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C alignment in union

In the K&R C programming code, the following code is given

typedef long Align;     /* for alignment to long boundary */

union header {          /* block header: */
    struct {
        union header *ptr;     /* next block if on free list */
        unsigned size;         /* size of this block */
    } s;
    Align x;            /* force alignment of blocks */
};

typedef union header Header;

Then it goes on to say that "The Align field is never used; it just forces each header to be aligned on a worst-case boundary". I have read the text multiple times but still do not understand why long is needed for alignment. SIZE is an int and PTR is 4 bytes, so shouldn't it be aligned anyways? And why use long, and not int? Thanks.

like image 828
George Newton Avatar asked Feb 12 '23 00:02

George Newton


1 Answers

That's a very old book. At the time a pointer on many machines was only 16-bits, and a long was 32-bits, so the union forced alignment to 32-bits.

And as @Deduplicator points out, there are still many embedded systems that use 16-bit pointers.


Edit in response to the comment: The topic of alignment is fairly broad and full of nuance. To keep things simple, the discussion that follows makes these assumptions

  • pointers are 16-bits
  • int is 16-bits
  • long is 32-bits
  • the processor has strict alignment requirements, i.e. 16-bit values can only be accessed on 2-byte boundaries, 32-bit values can only be accessed on 4-byte boundaries.

The following structure would occupy 32-bits

struct header {
    struct header *ptr;     
    unsigned size;         
};

However, the fields within the structure are still 16-bits each. Therefore, the alignment requirement is still only 16-bits. So for example, placing the structure at address 0xAA02 would be perfectly valid since ptr would be at an aligned address (0xAA02) and size would also be at an aligned address (0xAA04).

However, the address 0xAA02 is not suitably aligned for the union, since the x field of the union requires 32-bit alignment. Thus, placing the structure into a union with x forces the compiler to place the structure on a 4-byte boundary, when otherwise it could be placed on a 2-byte boundary.

like image 170
user3386109 Avatar answered Feb 13 '23 21:02

user3386109