4

I am working with some packet data. I have created structs to hold the packet data. These structs have been generated by python for a specific networking protocol.

The issue is that due to the fact that the compiler aligns the structures, when I send the data via the networking protocol, the message ends up being longer than I would like. This causes the other device to not recognize the command.

Does anyone know possible a work around this so that my packers are exactly the size the struct should be or is there a way I can turn off memory alignment?

Edwin
  • 797
  • 2
  • 14
  • 23

1 Answers1

6

In GCC, you can use __attribute__((packed)). These days GCC supports #pragma pack, too.

  1. attribute documentation
  2. #pragma pack documentation

Examples:

  1. attribute method:

    #include <stdio.h>
    
    struct packed
    {
        char a;
        int b;
    } __attribute__((packed));
    
    struct not_packed
    {
        char a;
        int b;
    };
    
    int main(void)
    {
        printf("Packed:     %zu\n", sizeof(struct packed));
        printf("Not Packed: %zu\n", sizeof(struct not_packed));
        return 0;
    }
    

    Output:

    $ make example && ./example
    cc     example.c   -o example
    Packed:     5
    Not Packed: 8
    
  2. pragma pack method:

    #include <stdio.h>
    
    #pragma pack(1)
    struct packed
    {
        char a;
        int b;
    };
    #pragma pack()
    
    struct not_packed
    {
        char a;
        int b;
    };
    
    int main(void)
    {
        printf("Packed:     %zu\n", sizeof(struct packed));
        printf("Not Packed: %zu\n", sizeof(struct not_packed));
        return 0;
    }
    

    Output:

    $ make example && ./example
    cc     example.c   -o example
    Packed:     5
    Not Packed: 8
    
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • 3
    IIRC, the `#pragma pack` is a hack for compatibility with MS compilers, and thus only avaliable for x86 targets. If you want to be portable to other targets (but not VC++) you should use the former. If you want both, you'll have to use `#ifdef`s. – rodrigo Aug 20 '13 at 17:42
  • I think it works for other targets too, but I'd have to check. – Carl Norum Aug 20 '13 at 17:46
  • 3
    @roderigo #pragma pack is for all architectures in gcc. There's a #pragma ms_struct on on some architectures that's for microsoft compatibility – nos Aug 20 '13 at 18:08
  • 2
    But see [this question](http://stackoverflow.com/q/8568432/827263); if you're not careful, `#pragma pack` can lead to unsafe code. – Keith Thompson Aug 20 '13 at 21:46
  • @KeithThompson, well as soon as you talk abut messing with the compiler options, you are talking about getting unsafe code. You just have to be really careful in either case. – Edwin Aug 20 '13 at 23:18
  • 1
    @Edwin: Not necessarily. For example, if `-O3` causes unsafe code, it's a bug (either in the compiler or in the code that it's compiling). – Keith Thompson Aug 20 '13 at 23:23