From the page you linked to:
The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.
For each member it takes the minimum alignment, between the member's optimal alignment and the pack value. The members in your example are aligned exactly the same regardless of pack(8)
and pack(16)
because the optimal alignment of the types are all less than 16.
If you had a member that required 16-byte alignment, such as __m128
, you would be able to find different results.