Why the size of the structure does not change when using a 24-bit integer

I am trying to port the code to a Windows platform. I ran into a problem below. I am posting sample code here. here even after I use the size int24, there are 12 bytes left on Windows, why?

struct INT24 { INT32 data : 24; }; struct myStruct { INT32 a; INT32 b; INT24 c; }; int _tmain(int argc, _TCHAR* argv[]) { unsigned char myArr[11] = { 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF }; myStruct *p = (myStruct*)myArr; cout << sizeof(*p); } 
+1
c ++
source share
2 answers

There are two reasons, each of which will be sufficient for yourself.

  • The size of INT32 is INT32 be 4 bytes. The size of INT24 also 4 bytes, because it contains the INT32 bit INT32 . Since myStruct contains 3 members of size 4, its size must be at least 12.
  • Presumably, the alignment requirement of INT32 is 4. Thus, even if the size of INT24 is 3, the size of myStruct should still be 12, since it should have at least the alignment requirement of INT32 and therefore the size of myStruct should be complemented to the nearest multiple of 4.

anyway or workaround?

This is implementation specific, but the following combination may work for some compilers / cpu combinations. Refer to your compiler’s manual for the syntax of a similar function and the manual for your target processor to see if it supports uneven memory access. Also understand that non-smooth memory access has a performance limitation.

 #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) 

Bitfield packing may not work the same in all compilers. Be sure to check how you behave.

I think the standard way would be to store char arrays of sizes 3 and 4, and whenever you need to read or write a single integer, you need a std::memcpy value. This would be a bit cumbersome to implement and perhaps also slower than hacking the #pragma package.

+3
source share

Unfortunately for you, the compiler, in optimizing the code for a particular architecture, reserves the right to set the structure by inserting spaces between members and even at the end of the structure.

Using a bit field does not reduce the size of a struct ; you still get the whole "fielded" type in the struct .

The standard ensures that the address of the first struct element matches the address of the struct , unless it is a polymorphic type.

But all is not lost: you can rely on the fact that the char array will always be contiguous and does not contain packaging.

If CHAR_BIT is defined as 8 on your system (perhaps it is), you can model an array of 24 bit types in a char array. If this is not 8, then even this approach will not work: I would suggest using the built-in assembly.

+1
source share

All Articles