Edit. I didn't see @salem c's post until after I posted this.
I know that sizeof(MyStruct) will give me 16 bytes. |
Yes, it would probably be 16 bytes. It's not guaranteed, however - we could conceive of a (probably stupid) implementation that would yield a larger struct.
When it comes to memory alignment however, does it actually take 16 bytes? |
Yes. Alignment is a property inherent to the
address of an object; the alignment of an object never affects that object's size.
The important distinction is that the alignment requirements of a
subobject can affect the alignment requirement and size of an object.
1 2 3 4 5 6
|
struct A { alignas(8) std::uint8_t x[1]; } a;
static_assert(sizeof(a) == 8);
static_assert(alignof(a) == 8);
static_assert(sizeof(a.x) == 1);
static_assert(alignof(a.x) == 8);
| |
If we use the memory optimization tool
pahole to examine the layout of A, we'll get the following. C++ comments are mine:
struct A {
// x[1] spans starts at offset 0, and ends at byte 1
uint8_t x[1]; /* 0 1 */
// The size of the structure is 8 bytes; it requires one cache-line
// The structure has one member.
/* size: 8, cachelines: 1, members: 1 */
// 7 total bytes of padding in the structure;
/* padding: 7 */
// The object requires only 8 bytes of its last cache-line
/* last cacheline: 8 bytes */
}; |
Pahole:
https://linux.die.net/man/1/pahole
Note that the type A is effectively the same as
std::aligned_storage_t<1, 8>.
I also assume it builds in the bitwise operations necessary to convert the alignment. |
I don't know what you mean. As I wrote above, alignment is inherent to the address of an object. Bitmath is not generally necessary (or even natural) to access an object that is naturally aligned.
Is it compiler dependent? |
Yes.
Do I need to provide my own bitwise logic in order to guarantee that the above structure only takes 16 bytes? |
If it's just a plain struct, make this static assertion:
|
static_assert(sizeof(MyStruct) == 16);
| |
If you need to pack or unpack structures that are not naturally aligned, you can use vendor-specific language extensions, e.g., the GCC attribute
[[gnu::packed]] to allow the compiler to misalign the members of a class, or use
std::memcpy as I discussed before. Misaligned accesses are undefined behavior; be careful.
I suggest that you play around with
pahole on Matt Godbolt's page:
https://godbolt.org/z/UqlG-G