ethc
ethc

Reputation: 153

Define a packed version of a C struct

I have a C structure defined somewhere outside my code. Can I define a packed version of the same structure? If I define my own structure from the start, that is easy:

struct test {
    // members
} __attribute__((packed));

I defined a simple structure and tried two possibilities, this:

struct test {
    int x;
    double y;
    char z;
};

struct test_p {
    struct test __attribute__((packed)) s;
};

and this:

struct test {
    int x;
    double y;
    char z;
};

struct test_p {
    struct test p;
} __attribute__((packed));

However, neither of these work (both compile fine though) printing sizeof(struct test_p)=24 on my system (I use gcc 4.8.2 on a 64-bit machine) which is the same as sizeof(struct test). Is there a way to achieve the desired effect?

Just in case you were wondering: I want to parse packets received over network which are just packed structures. The thing is, I can't modify the header file because it is a part of a third-party library, and the structure itself contains too many fields to copy them one by one. I can certainly copy the structure definition to my own header and make the packed version -- actually it is the solution I'm using now -- but I was just wondering if there is a more concise solution which does not involve copying the whole definition.

Upvotes: 4

Views: 1848

Answers (1)

Dummy00001
Dummy00001

Reputation: 17450

The gcc has introduced the __attribute__((packed)) precisely to avoid the dangerous effects you are seeking: the definition of the structure should binary compatible between all the user applications and libraries which use the same definition.

But the gcc also provides a way to do the packing the old fashioned, dangerous way - #pragma pack(push,n) and #pragma pack(pop). It would work reliably only if the 3rd party header file contains solely the structure definition, or you do not use anything else from the header. Use them like that:

#pragma pack(push,1)
#include "theheader.h"
#pragma pack(pop)

Otherwise, I personally would have simply copy-pasted the structure definition, renamed it, and added __attribute__((packed)) in my own header. Packing with pragmas the whole header is really a dirty hack. And 3rd party headers might change in unexpected ways, contributing to the bit rot.

Upvotes: 2

Related Questions