This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

create a packed struct

Long story short, I need to create a packed struct.

I knew the pragma way, to change aligment, didn't work. I looked up and found the __packed (I'm using Keil µVision) here: www.keil.com/.../armcc_chr1359124229695.htm

So in the end, here's my theoritically bulletproof code:

#pragma pack(push)
#pragma pack(1)

__packed struct PackedStructure
{
  __packed uint16_t packedValue;
};

#pragma pack(pop)

And now what does sizeof(struct PackedStructure) return ? 4...

Note I've tried pretty much any combination of pragma pack and __packed on structure/member, with always the same result.

And this:

typedef __packed __attribute__((packed)) __attribute__((aligned(1))) struct
{
  __packed uint16_t packedValue;
  __packed uint16_t packedValue2;
} Event;

Gives me a size of 8.

Anyone can tell me how to get a packed structure? Thanks!

  • @awneil, right, I'll ask on Keil's forum too. As to why I need it... you never need packed structures, it's a convenience, what I need is to save space (not using 32 bits for a boolean), and what I want on top is a convenient way of doing it.

  • @Keton this is very interesting, using Keil 5.22 too, and the unpacked structure gives me 4 bytes. Now, could your platform be 16 bits aligned?

  • @Jonathan I've checked this on x64 using gcc, nRF52 using both Keil and gcc and Raspberry pi using gcc. Each time following code:

    typedef struct
    {
    	uint16_t test;
    } short_single_t;
    
    typedef struct
    {
    	uint16_t test;
    	uint16_t test2;
    } short_double_t;
    
    struct PackedStructure
    {
      uint16_t packedValue;
    };
    
    #ifdef NRF52
    #define printf NRF_LOG_INFO
    #endif
    
    static void struct_size_test(void)
    {
    	printf("sizeof(short_single_t)==%zu\n",sizeof(short_single_t));
    	printf("sizeof(short_double_t)==%zu\n",sizeof(short_double_t));
    	printf("sizeof(struct PackedStructure)==%zu\n",sizeof(struct PackedStructure));
    }
    

    gives me this result:

    sizeof(short_single_t)==2
    sizeof(short_double_t)==4
    sizeof(struct PackedStructure)==2
    

    According to this guide behavior I see is mandated by C standard. Shorts (uint16_t is short) are self-aligned to 2 byte boundary so struct containing only shorts will have 2 byte alignment and no padding.

  • Thank you very much for your test. I have some other softwares in which I use #pragma pack(1), compiled with GCC and executed on RPi, and I have no problem with that (ie, packing occurs). And now you said that with Keil 5.22, and various other compilers, you get the proper result. So far, my conclusion is there's an issue with my Keil/compiler configuration at some point.

  • The one thing that comes to my mind, but I don't know enough about it to be sure, is that for some reason, your code could be compiled to Thumb instructions, which I assume forces 16 bits aligment. Complete guess, I don't know what would cause Thumb vs ARM compilation, and I'm unsure Thumb uses 16 bits alignments.

Related