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?
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.