strange behaviour of function sizeof() with a structure

I have the following structure:

struct ST_FORM_PARAM1
{
uint8_t NomeForm[8];
uint32_t Ritardo[2];
uint16_t Velocita;
uint16_t PowerOnMode;
uint16_t CRCFormPar1;
};

struct ST_FORM_PARAM1       FormPar1;

When I use the function sizeof(FormPar1) in the program, the result is 24 byte but is wrong because the structure is composed by 22 byte.

In the picture the result from e2studio shows that adressing is correctly aligned and the size of the structure is 22 byte.

 

If the structure is modified transforming uint32_t Ritardo[2] in uint16_t Ritardo[4] the result of sizeof() is correct.

Somebody can explain me this crazy behaviour ?

  • If in the oroginal structure I add a variable uint16_t AUX1 the result of sizeof(FormPar1) is 24 byte again, but this time is correct.......
  • In reply to Lui Luigi:

    Hi

    It's common phenomenon regarding structures in 32 bit MCU. Please read this post (you must use 

    __attribute__((__packed__)) 

    with the structure declaration.

  • In reply to HENIUS:

    Thank you Henius for replying.
    I'm very aware of the behaviour described in your link. The problem is that my structure is correctly aligned with a multiple of 4, as also witnessed by the imagine of adresses in e2studio. I'm convinced this is a bug....
  • In reply to Lui Luigi:

    Everything works fine. In your structure additional 2 bytes are added at end of memory block.
    Please implement this structure:


    struct S {
       int16_t member1;
       int32_t member2;
    };

    and you will see how it works.

  • In reply to HENIUS:

    Yes, I know very well that 2 byte are inserted between member1 and member2, but it'not my case. In my structure every uint_32 member has the correct adressing in term of multiple of 4 and every uint_16 member has an adress multiple of 2. As you can see from the image, if I calculate the size of the structure in term of addresses, (as a matter of fact is what I did in the program), you obtain the correct size: StructSize=(uint8_t*)&FormPar1.CRCFormPar1-(uint8_t*)&FormPar1+2; The result is 22 and is correct but it's different from the result of sizeof(). If you repeat the same calculus in your structure, the result is the same as sizeof() because of the 2 byte inserted by the compiler.
  • In reply to Lui Luigi:

    Is this the reason for the difference in reported size of the structure?

    The sizeof() operator returns the number of bytes the compiler has allocated to store the structure.
    The space required to fit the individual parts of the structure is 22 bytes.
    On a 32-bit platform and without the packed declaration, the compiler will allocate multiples of 32-bits (24 bytes) leaving 2 unused bytes at the end.

    You could confirm this by declaring an array of struct ST_FORM_PARAM1 and confirming that each element starts on a 32-bit boundary.

    If you add the __attribute__((__packed__)) you will find the second element does not start on a 32-bit boundary and the spare bytes have gone. Accessing the 'Ritardo' values may cause an error as they are not always on a 32-bit boundary.
  • In reply to Lui Luigi:

    The padding occurs at the end of the structure to align the next variable on a 32 bit aligned address (the default) (there are 3 * 16-bit members at the end of the structure, so padding of 16 bits is added to the structure) :-

     

     

    If you request no padding using __attribute__((packed));  the structure size is as you expect :-

    and the start address of FormPar1[1] is on a 16 bit boundary in this case, rather than a 32 bit boundary.

  • In reply to Jeremy:

    Ok guys, thank you to everyone. I'll take care in using sizeof() in future...