Because of your ULONGLONG
first member, your structure will have 8-byte (64-bit) alignment. Assuming 32-bit ints, your first version uses 18 bytes, which would take 24 bytes to store. (The large and small members are interspersed, which makes the matter worse, but by my count, that doesn't change the answer here.) Your second version also takes 18 bytes:
- 8 bytes for
m_uField1
- 4 bytes for
m_uField2
- 2 bytes for
m_sField4
- 4 bytes for the two
unsigned
bitfields (which will have 4-byte alignment, so will also inject 2 bytes of padding afterm_sField4
)
If you switch to short unsigned m_bField3:1
and short unsigned m_bField4:1
, I think there's a good chance your structure will become smaller and fit in only 16 bytes.
Use of #pragma pack
is not portable, so I can't comment on the specifics there, but it's possible that could shrink the size of your structure. I'm guessing it may not, though, since it's usually better at compensating for nonoptimal ordering of members with alignment, and by my counts, your variables themselves are just too big. (However, removing the alignment requirement on the ULONGLONG
may shrink your structure size in either version, and #pragma pack
may do that.)
As @slater mentions, in order to decrease the size and padding in your structure, you should declare your member variables of similar sizes next to each other. It's a pretty good rule of thumb to declare your variables in decreasing size order, which will tend to minimize padding and leverage coinciding alignment requirements.
However, the size of the structure isn't always the most important concern. Members are initialized in declaration order in the constructor, and for some classes, this matters, so you should take that into account. Additionally, if your structure spans multiple cache lines and will be used concurrently by multiple threads, you should ideally put variables that are used together nearby and in the same cache line and variables that are not used together in separate cache lines to reduce/eliminate false sharing.