The size of the 64-bit structure of Windows depends on the data type?

I have two different data structures that should basically be the same size, and I wonder why they don't.

struct pix1 { unsigned char r; unsigned char g; unsigned char b; unsigned char a; unsigned char y[2]; }; struct pix2 { unsigned char r; unsigned char g; unsigned char b; unsigned char a; unsigned short y; }; 

Then I group four of these pixels together:

 struct pix4 { pix1 pixels[4]; // or pix2 pixels[4] unsigned char mask; }; 

... but it turns out that the size of such a grouping changes in accordance with sizeof (pix4), depending on whether I use pix1 or pix2. Individual sizeof (pix1) == sizeof (pix2), so I'm confused about why the grouping of quartets of pixels changes size. I care because it’s easier to write programs with shorter than two unsigned characters, but it costs me 0.25 bytes per pixel.

I am not sure if this architecture is specific as I have not tested other types of machines. Could it be? Is this something I need to worry about, or can I start a short implementation?

Thanks for your help in advance.

+4
source share
3 answers

The size of the structures is the same, but their alignment requirements are different.

Alignment of the structure is the maximum alignment of all its members. So pix1 has alignment 1 because it only has characters, but pix2 has alignment 2 from the short term. Then alignment pix4 receives alignment from the pixels member, so it is 1 in the first and 2 in the second case.

Now, so that all elements of the array are correctly aligned, the size of the structure is rounded to the next multiple alignment. In both cases, the size of pixels is 24, but then there is a 1-byte mask . In the first case, the alignment is 1, so 25 is a multiple of it, and sizeof(pix4) is 25, and in the second, the alignment is 2, so sizeof(pix4) needs to be rounded to the next even number, 26.

This is the same on all platforms.

+9
source

Yes, this is due to alignment. The compiler wants to align the variables at natural boundaries , so the short one will be aligned to 16 bits (2 bytes). And therefore, the structure containing the short one will also be aligned on the 16-bit boundary.

+2
source

The same goes for 32-bit Linux.

This is due to the addition for alignment.

If you use struct pix1 , you only have characters and therefore struct pix4 can be left as is. But if you use struct pix2 , it contains a short one. Thus, the entire structure must be aligned, so that even in the struct pix4 each element is aligned for clean access to y .

More detailed: A strict pix4 with two elements will have the form:

  +----- [0] -----+++----- [1] -----+ First version: rgbayyrgbayyrgbayyrgbayyMrgbayyrgbayyrgbayyrgbayyM Second version: rgbayyrgbayyrgbayyrgbayyM rgbayyrgbayyrgbayyrgbayyM ---------25--------------+ <- +1 

Why? Since the --- ed part is 25 bytes, which is an odd number. This is not a problem for the first version - the second element can happily start with an odd address, but for the second version. There yy should always be on an even (aligned) address, so struct pix4 is 26 bytes.

+1
source

Source: https://habr.com/ru/post/1416103/


All Articles