This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to pack structs?

I'm using the Keil uVision3. How do I pack structs?

Do I use __packed or is there a pragma?

is this correct? it doesn't compile...

typedef struct
{ UINT8 key_diff; UINT8 key_state;
} __packed SCmd_KeyPress;

Parents
  • I'll give you a real example.
    back in the late 80's I was working with the Franklin compiler. Remember that? it was actually the first Keil compiler rebranded by franklin. That code created a buffer of data bytes in a structure and sent them out to a PC. The PC code was written in microslut C 1.5. The interrupt routine would buffer the characters into a buffer, which I then overlayed with the C structure from the 8051. Nothing matched up right. Turned out that structures in the microslut compiler had padding inserted, and that made the structure not line up right.

    If you have a mixed structure, say one with a generic pointer and a memory typed pointer in the Keil compiler, and attempt to access it with an overlay of another structure, you will find that you have alignment problems, because of the extra padding byte (memory address type) that the compiler put in behind the scenes for a generic pointer.
    So there can be structure misalignments even on the 8051.
    Cheers

Reply
  • I'll give you a real example.
    back in the late 80's I was working with the Franklin compiler. Remember that? it was actually the first Keil compiler rebranded by franklin. That code created a buffer of data bytes in a structure and sent them out to a PC. The PC code was written in microslut C 1.5. The interrupt routine would buffer the characters into a buffer, which I then overlayed with the C structure from the 8051. Nothing matched up right. Turned out that structures in the microslut compiler had padding inserted, and that made the structure not line up right.

    If you have a mixed structure, say one with a generic pointer and a memory typed pointer in the Keil compiler, and attempt to access it with an overlay of another structure, you will find that you have alignment problems, because of the extra padding byte (memory address type) that the compiler put in behind the scenes for a generic pointer.
    So there can be structure misalignments even on the 8051.
    Cheers

Children
  • "If you have a mixed structure, say one with a generic pointer and a memory typed pointer in the Keil compiler, and attempt to access it with an overlay of another structure, you will find that you have alignment problems"

    That has nothing whatsoever to do with alignment or packing - they are just two differently-sized data types!

    "extra padding byte (memory address type)"

    It is not a padding byte - it is a "functional" byte that carries additional information.

    "compiler put in behind the scenes for a generic pointer."

    It's not "behind the scenes" - it is a fully documented, essential part of a Keil C51 Generic Pointer!

  • I'll give you a real example.

    That's actually just an example of what one should not do with C data structures structs. C structs have no business being copied or used outside the internals of a C program. You haven't demonstrated a problem with struct packing, but one with the design of that program.

  • The most common - and probably the only valid reason - for packing structures is to save space when doing embedded work. It is a trade-off between data size and code size, and often also a trade-off in speed.

    If you need to work with hardware, or write data to a file or build packets for transfer over a network, you should instead byte-pack your data yourself, similar to:

    pos = packet.data;
    pos = insert_u8(pos,my_8bit_value);
    pos = insert_u16(pos,my_16bit_value);
    ...
    assert(pos - packet.data == expected_packet_size);
    

    The reason for this is that when permanently storing information, or accessing hardware or communicating, you have more things to take into account. A packed structure will just save you the extra space between individual members, but may still have the incorrect byte order.