TAlignedBytes definition is picked from ue4,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | typedef unsigned char uint8; typedef int int32; typedef unsigned int uint32; template<int32 Size, uint32 Alignment> struct TAlignedBytes; // this intentionally won't compile, we don't support the requested alignment /** Unaligned storage. */ template<int32 Size> struct TAlignedBytes<Size, 1> { uint8 Pad[Size]; }; #define GCC_ALIGN(_align) #define MS_ALIGN(n) __declspec(align(n)) // C++/CLI doesn't support alignment of native types in managed code, so we enforce that the element // size is a multiple of the desired alignment #ifdef __cplusplus_cli #define IMPLEMENT_ALIGNED_STORAGE(Align) \ template<int32 Size> \ struct TAlignedBytes<Size,Align> \ { \ uint8 Pad[Size]; \ static_assert(Size % Align == 0, "CLR interop types must not be aligned."); \ }; #else /** A macro that implements TAlignedBytes for a specific alignment. */ #define IMPLEMENT_ALIGNED_STORAGE(Align) \ template<int32 Size> \ struct TAlignedBytes<Size,Align> \ { \ struct MS_ALIGN(Align) TPadding \ { \ uint8 Pad[Size]; \ } GCC_ALIGN(Align); \ TPadding Padding; \ }; #endif // Implement TAlignedBytes for these alignments. IMPLEMENT_ALIGNED_STORAGE(16); IMPLEMENT_ALIGNED_STORAGE(8); IMPLEMENT_ALIGNED_STORAGE(4); IMPLEMENT_ALIGNED_STORAGE(2); #undef IMPLEMENT_ALIGNED_STORAGE |
My test code is in vc2019 x64,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | struct TTask { char ch2; char ch3; double d4; __int64 i64; }; #pragma pack(push, 1) struct TTaskB { char ch2; alignas(16) char ch3; double d4; __int64 i64; }; struct AAa { char ch1; TAlignedBytes<sizeof(TTask), alignof(TTask)> TaskStorage; }; struct AAb { char ch1; TTask TaskStorage; }; #pragma pack(pop) void CMFCApplication1Dlg::OnBnClickedButton1() { __int64 sizeTTask = alignof(TTask); // sizeTTask is 8 __int64 sizeTTaskB = alignof(TTaskB); // sizeTTaskB is 16 AAa aa; TTask& Task = *(TTask*)&aa.TaskStorage; __int64 gapAAa = (char*)&Task - (char*)&aa; // gapAAa is 8 AAb bb; TTask& TaskB = *(TTask*)&bb.TaskStorage; __int64 gapAAb = (char*)&TaskB - (char*)&bb; // gapAAb is 1 } |