aleix's blog

Be careful with packed structures!

24 July 2007 3:07 pm (c)

If you use the C language, you may have probably wanted to pack your structures so no alignment is done by the compiler. This can be useful for example to build network packets. You can find the basics of packed structures using GCC, here or here.

If everything seems clear, why am I writing this? Today, a coworker has found a bug related to packed structures. The issue was with internal structures (i.e. a substructure). A year ago, or so, I knew that substructures were not packed even if its enclosing structure is packed, but it seems I forgot about it, so I have decided that it was worth writing it here so I do not forget it again (I'm sure I will).

I will take the example found in GCC documentation (only since version 3.4.0). Suppose you have the following code:

struct my_unpacked_struct
{
  char c;
  int i;
};

struct my_packed_struct
{
  char c;
  int  i;
  struct my_unpacked_struct s;
} __attribute__ ((__packed__));

struct my_packed_struct my = {
  .c = 10,
  .i = 20,
  .s.c = 30,
  .s.i = 40
};

If we generate the assembly for this (I have omitted some things not needed for the example), we will get:

        .globl _my
        .data
_my:
        .byte   10  <--- c
        .long   20  <--- i
        .byte   30  <--- s.c
        .space 3    <--- 3 bytes of alignment
        .long   40  <--- s.i

As you can see, the compiler has not aligned the internal structure, but the enclosing one. So, what you need to do if you want the internal structure also packed is to pack my_unpacked_struct:

struct my_unpacked_struct
{
  char c;
  int i;
} __attribute__ ((__packed__));

Now, we get what we initially expected:

        .globl _my
        .data
_my:
        .byte   10  <--- c
        .long   20  <--- i
        .byte   30  <--- s.c
        .long   40  <--- s.i

Packing the whole structure my_unpacked_struct is fine if you do not use it anywhere else, but it would be great to use variable attributes (we have used type attributes so far), so we could only pack the internal substructure variable like this (it doesn't work):

struct my_packed_struct
{
  char c;
  int  i;
  struct my_unpacked_struct s __attribute__ ((__packed__));
} __attribute__ ((__packed__));

Update 2007/07/25: read the first comment to understand why the variable attribute is not working in this case.

By the way, in the example I have initialized the structure my using designated initializers.

And remember, be careful with packed structures!

21 responses

  1. drj11 says:

    It pretty much has to work this way. Consider what happens when I have a random pointer to the unpacked struct:

    struct my_unpacked_struct *p;
    p = ...;
    printf("%d\n", p->i);

    When the compiler is generating code for «p->i» it has to know what the offset is to get from the beginning of the struct to the "i" field. This is a fact about the struct, not about where the struct is. The compiler can't tell whether the pointer p points to an "ordinary" struct my_unpacked_struct or one that is embedded inside another (packed) struct. There's no difference. The pointer doesn't stored any information that will allow it tell.

    That's why embedding a struct can't change how the embedded struct is packed.

    There's another reason you should be careful with packed structures: they're non-standard.

  2. aleix says:

    I see... this is why variable attribute is not working for the internal structure, so you are forced to pack the type if you want it to be packed.

    As you say, this is a non-standard feature (even most compilers support it), and of course it has a lot of performance penalties as the compiler needs to generate code to unpack unaligned data. We're using it to easily represent network packets in C, and we found that it was a pretty good way (at list for writing the code to manage packet fields).

    Thanks!

  3. nico says:

    So you're doing something like that:
    struct my_packed_struct s;
    read_from_net(&s, sizeof(s));
    /* ... */
    do_stuff(s.i)
    ? That will crash on everything but on x86 architectures, because usually you can't read integers on non-word boundaries. Packed structures are very unportable.

  4. aleix says:

    Yes, it's true that packed structures are not really recommended because of portability. I'm using them on an embedded system with an SPARC CPU and they work fine (in this project), I don't really see why your code doesn't work (what is the read_from_net function doing?). If you have a buffer with the data coming from the network and just memcpy it to the address of your packed structure it works fine, you only need to take into account the endianess, all the rest (field alignment) is automatically done by the compiler.

  5. college paper writing service says:

    useful

  6. MathCad Online Assignment Help says:

    Things are very open and intensely clear explanation of issues. was truly information. Your website is very beneficial.

  7. buy harvard or Ivey case study solutions says:

    Pretty helpful material, much thanks for this article

  8. assignment writing help says:

    Science Channel’s are giving a complete knowledge to its viewers about every thing students write done dissertation on this subjects and show its importance.

  9. Mike says:

    Very well written article about C language. You have made a great effort in making this post which i appreciate it a lot. I must say you have made a great effort in making this post.Garage Shelving

  10. translation price per word says:

    I will share to your post different website or friendz.this post rightly helpful for business work.continuetranslation price per word

  11. Alice says:

    Thank you for your sharing.

  12. see page says:

    I likr these tutorials

  13. brown says:
  14. Veronica says:

    Dear writer! Thank you so a lot for staying here and posting so well content. Here is anyone who enjoy it and state thanks!

  15. Claudia says:

    In my view, not numerous blogers own so countless concepts to produce brand new, absorbing content. Many thanks for undertaking it and I hope you didn't lose the motivation to write the unique ones!

  16. Isabel says:

    I totally agree with the past audience. I think the ideal inspiration and great suggestions are wonderful basis to make top quality information.

  17. Jenny says:

    I have always thought about how to compose top superiority content and distribute them on the site. These days I must state that the work isn't for me. I leave it for professional writers.

  18. Alexia says:

    Hey every girl! It truly is very exciting document. I'm amazed that you are so gifted. I don't worth you!

  19. Nora says:

    Congratulation on creating stunning documents! I need state that the article is a maximum grade content and it fulfils all kinds of standards. Well-done.

  20. Peyton says:

    Hey. Here is a concern for every person who look for big excellence reports. Will you seek another blog? If you question me I will state NO. This site is ideal for myself!

  21. Capri says:

    Hi publisher! Thank you for getting here and placing so well articles. There is someone who love it and express thank you so much!

Leave a Reply