Consider struct Y { __declspec(align(128)) int i:1; }; struct Z { char c; struct Y y; }; int f(void) { return _Alignof(struct Y); } int g(void) { return sizeof(struct Z); } int h(void) { return &((struct Z *)0)->y; // offsetof(struct Z, y) } MSVC returns 128 16 8 clang returns 128 256 128 on the aarch64-pc-windows-msvc target. Apparently, on ARM targets, bitfields in structs increase the alignment of the struct to at most 8 bytes. Even though _Alignof incorrectly returns a higher value.
After some testing, the real behavior seems to be as follows: // The effect of #pragma pack(N) depends on the target. // // x86: By default, there is no maximum field alignment. N={1,2,4} set the maximum field // alignment to that value. All other N activate the default. // x64: By default, there is no maximum field alignment. N={1,2,4,8} set the maximum field // alignment to that value. All other N activate the default. // arm: By default, the maximum field alignment is 8. N={1,2,4,8,16} set the maximum field // alignment to that value. All other N activate the default. // arm64: By default, the maximum field alignment is 8. N={1,2,4,8} set the maximum field // alignment to that value. N=16 disables the maximum field alignment. All other N // activate the default. struct A { __declspec(align(128)) int i:1; }; struct B { struct A x; }; #pragma pack(4) struct C { struct A x; }; #pragma pack() #pragma pack(8) struct D { struct A x; }; #pragma pack() #pragma pack(16) struct E { struct A x; }; #pragma pack() #pragma pack(32) struct F { struct A x; }; #pragma pack() static void f(void) { #if defined(_M_IX86) static_assert(_Alignof(struct B) == 128, ""); static_assert(_Alignof(struct C) == 4, ""); static_assert(_Alignof(struct D) == 128, ""); static_assert(_Alignof(struct E) == 128, ""); static_assert(_Alignof(struct F) == 128, ""); #elif defined(_M_X64) static_assert(_Alignof(struct B) == 128, ""); static_assert(_Alignof(struct C) == 4, ""); static_assert(_Alignof(struct D) == 8, ""); static_assert(_Alignof(struct E) == 128, ""); static_assert(_Alignof(struct F) == 128, ""); #elif defined(_M_ARM) static_assert(_Alignof(struct B) == 8, ""); static_assert(_Alignof(struct C) == 4, ""); static_assert(_Alignof(struct D) == 8, ""); static_assert(_Alignof(struct E) == 16, ""); static_assert(_Alignof(struct F) == 8, ""); #elif defined(_M_ARM64) static_assert(_Alignof(struct B) == 8, ""); static_assert(_Alignof(struct C) == 4, ""); static_assert(_Alignof(struct D) == 8, ""); static_assert(_Alignof(struct E) == 128, ""); static_assert(_Alignof(struct F) == 8, ""); #else static_assert(0, "unknown target"); #endif }