Search code examples
cmemory-alignmentpragma-pack

Why #pragma pack also affects structs' own alignment?


I noticed that when #pragma pack is used around a struct, the alignment inside of it is not the only one that is affected, but also the alignment of the struct itself changes. Consider the following:

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

#pragma pack(1)
typedef struct _TEST
{
    uint32_t a;
} TEST;
#pragma pack()

volatile uint8_t n;
TEST b;

int main()
{

    printf("Address %lX rem %lu\n", (long unsigned int)&b, (long unsigned int)(&b)%(sizeof(int)));  
    return 0;
}

You can try this code is here: https://onlinegdb.com/BkebdxZEU

The program returned Address 601041 rem 1, which means that the pragma also had an effect of aligned(1) on the struct.

Why is that? Is this a defined behavior?


Solution

  • The alignment of a structure is affected by the alignment requirements of its members. A structure as a whole is usually aligned to the alignment of its largest member. Because your struct contained a uint32, it would have been aligned to four bytes, had you not invoked the #pragma before.

    However, with #pragma pack(1), you force the alignment required for all its members to 1-byte (or no alignment) and hence the structure can now start at any address in memory, not necessarily at a multiple of four bytes.