LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Structure packing behavior

Hi 🙂

- It took me some days to understand that my problem does relate to the structure packing behavior of compiler.
- Now I understand that I can solve my problem with #pragma pack.
- But since it took me a long time, so I want to get to understand the packing behavior a little bit more, may be someone can help explain it to me 🙂

my little code:
typedef struct {
unsigned char LittleCow1;
unsigned char LittleCow2;
} CowFamily;

- In this case, sizeof(CowFamily) will be 2, that is, 1 for each little cow, but if I change the code to
typedef struct {
unsigned char LittleCow;
unsigned int CowMom;
} CowFamily;

- sizeof(CowFamily) become 8, I understand that the compiler will start to pack the whole structure on to 4 bytes boundary if there is any 32-bit(or more) element inside the structure, correct? Is there any place where I can find more information regarding this behavior ?

- I meet this issue because I try to manage the structure using char *.

Thank you :)))
- Mole -
0 Kudos
Message 1 of 6
(4,361 Views)
Liitle Mo -

The Tartan book, C A reference Manual, Harbison & Steele contains a good explanation of C struct packing issues.  ISBN 0-13-089592-X

They say:

1. A struct must terminate on the same alignment boundary on which it started.
2, The alignment requirement for a struct will be at least as stringent as for the component having the most stringent requirements.
3. Alignment requirements may cause padding to appaear in the middle of a struct.

Hayes
0 Kudos
Message 2 of 6
(4,327 Views)
Hayes,

Thank you for the information, I will look into that
book right away 🙂

- Mole -
0 Kudos
Message 3 of 6
(4,310 Views)
But caution: for everything else than Byte alignment the padding behavior is compiler dependant! (Old DOS compilers vs. current compilers)
-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 4 of 6
(4,295 Views)

Default structure alignment should reflect the _DEFALIGN macro that you can find under Build options >> Predefined macros menu item. In case you need to share data in binary format between programs written with different versione of CVI or from different compilers you may have a packing problem. For example, defalign macro defaults to 8 starting from cvi 6 on, but in the past I had some problems upgrading a program from cvi 5.5 (_DEFALIGN = 1) to newer versions of the compiler.

In this case you may need to use push and pop modifiers to define some structure with a different alignment than the default uset in the rest of your program. CVI online help describes this procedure; some examples of this usage can be found in several cvi standard include file (for example float.h).



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 6
(4,291 Views)


@Little_Mole wrote:
Hi 🙂

- It took me some days to understand that my problem does relate to the structure packing behavior of compiler.
- Now I understand that I can solve my problem with #pragma pack.
- But since it took me a long time, so I want to get to understand the packing behavior a little bit more, may be someone can help explain it to me 🙂

my little code:
typedef struct {
unsigned char LittleCow1;
unsigned char LittleCow2;
} CowFamily;

- In this case, sizeof(CowFamily) will be 2, that is, 1 for each little cow, but if I change the code to
typedef struct {
unsigned char LittleCow;
unsigned int CowMom;
} CowFamily;

- sizeof(CowFamily) become 8, I understand that the compiler will start to pack the whole structure on to 4 bytes boundary if there is any 32-bit(or more) element inside the structure, correct? Is there any place where I can find more information regarding this behavior ?

- I meet this issue because I try to manage the structure using char *.

Thank you :)))
- Mole -

Actually the rule about packing is quite simple. A structure element will be packed on a multiple of the smaller value of the two that are:

1)  the packing alignment set for the current code block, eg. #pragma pack(x) for MS VC and compatibles or #pragma option -a1 and friends for Borland and if no packing pragma is set the default packing for the project, which nowadays is mostly set to 8.

2) And the basic size of the structure element as evaluated by sizeof(), meaning a fixed size array of chars is aligned to 1 byte no matter how many fixed size chars it contains, but a string pointer will usually be aligned to 4 bytes (8 for 64bit systems) unless rule 1) applies.

This applies to x86 systems mostly. Other architectures such as Sparc may enforce strict alignement for pointers for instance since accessing an operand on non aligned addresses has a terrible performance on these.

Rolf Kalbermatter

Message Edited by rolfk on 05-16-2006 10:18 AM

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 6 of 6
(4,292 Views)