This is the over-smart method of doing this, using the precompiler:
mydata-fields.h
FIELD(int, one)
FIELD(char, two)
FIELD(long, three)
mydata.h
#define FIELD(t, n) t n;
struct MyData
{
#include "mydata-fields.h"
};
struct __attribute__((packed)) MyDataPacked /*or whatever your compiler needs */
{
#include "mydata-fields.h"
};
#undef FIELD
#define FIELD(t, n) a->n = b->n;
static inline void Unpack(MyData *a, MyDataPacked *b)
{
#include "mydata-fields.h"
}
static inline void Pack(MyDataPacked *a, MyData *b)
{
#include "mydata-fields.h"
}
#undef FIELD
UPDATE: With a bit of imagination you can even write a generic packed.h that receives the names of the struct and the fields file as parameters:
extract of packed.h
/* ... */
struct UNPACKED
{
#include FIELDS_H
};
/* and so on... */
And then simply in the real file:
mydata.h
#define UNPACKED MyData
#define PACKED MyDataPacked
#define FIELDS_H "mydata-fields.h"
#include "packed.h"
#undef FIELDS_H
#undef PACKED
#undef UNPACKED
This will be useful if you have a lot of packed/unpacked structures and want to avoid some typing.
A not so evil solution would be to write a script (in Python!) that generates the code from the fields specification in some input text file.