There are two reasons, each of which would be enough by themselves.
- Presumably the size of
INT32
is 4 bytes. The size of INT24
is also 4 bytes, because it contains a INT32
bit field. Since, myStruct
contains 3 members of size 4, its size must therefore be at least 12.
- Presumably the alignment requirement of
INT32
is 4. So, even if the size of INT24
were 3, the size of myStruct
would still have to be 12, because it must have at least the alignment requirement of INT32
and therefore the size of myStruct
must be padded to the nearest multiple of 4.
any way or workaround ?
This is implementation specific, but the following hack may work for some compilers/cpu combinations. See the manual of your compiler for the syntax for similar feature, and the manual for your target cpu whether it supports unaligned memory access. Also do realize that unaligned memory access does have a performance penalty.
#pragma pack(push, 1)
struct INT24
{
INT32 data : 24;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct myStruct
{
INT32 a;
INT32 b;
INT24 c;
};
#pragma pack(pop)
Packing a bit field might not work the same in all compilers. Be sure to check how yours behaves.
I think that a standard compliant way would be to store char arrays of sizes 3 and 4, and whenever you need to read or write one of the integer, you'd have to std::memcpy
the value. That would be a bit burdensome to implement and possibly also slower than the #pragma pack hack.