how to pack strutures?

Hello,

I must have packed some of my struts, but the GNU compiler ignored my commands.

Here are three examples of my structs:

struct s_speicher1 {
char x;
int z;
};

struct s_speicher1 {
char x;
int z;
} attribute ((packed));

struct s_speicher2 {
char x attribute ((packed));
int z attribute ((packed));
};

All of these tree examples have a size of 8 byte.

What can I do, that the compiler packed my specified structs?

thanks,
Frank

Frank,

Structure packing is working for me, when packing the structure as a whole, in so much as the sizeof() the packed structure using:

struct s_speicher1 {
char x;
int z;
} attribute ((packed));

is 5 bytes, vs. the unpacked size of 8 bytes.

Packing each individual struct element, as your thrid example shows is, as I understand it is a C++ convention and will not work in C.

The use of packed structures on an ARM platform is not recommended. The attached document, taken from the ARM Architecture Reference Manual; second edition (ISBN 0-201-73719-1), explains that unaligned memory accesses can and most often will produce unexpected results.

In my experience developer frequently make use of packed structures for easy data handle of protocol implementations. Typically a protcol packet can be represented as a packed structure.

We would recommend that you not pack your structures, but instead memcpy() the necessary data into an appropriately sized buffer; then use that buffer for data transmittal.

Cameron

The structure packing stuff does not work very well. Use a separate buffer and cast pointers into the buffer.

char buffer[256];

#define mystruct.ms_label ((char )&buffer[0])
#define mystruct.ms_size (
(unsigned long )&buffer[64])
#define mystruct.ms_date (
(time_t *)&buffer[68])

etc.

This is what you need to do for any predefined structures. (Such as in RFCs.)

-Erik

thanks for your responses.

That Structure that i want to pack is not the little that i have post. It was a complex structure with structs integrated and so on. And the packed structure comes from a 8bit Controller over the UART.
When there is no goog Methode to handle this i must programm a funktion to convert the sended block in my unpacked struct.

Frank

I had recently a bad experience with structure alignment. Bit more complicated than the example here – I have structure pointers that are assigned to point to pre-defined array of elements (it was the “easy” way to translate messages between protocols/platforms). For example, I had :

typedef struct {
WORD16 var_index;
float data;
WORD16 command;
} FltArrayType;

FltArrayType *FltArrayPtr1;

WORD16 holding_regs[65535];

FltArrayPtr1 = (FltArrayType *) &holding_regs[500];

I assumed (wrong) that:

FltArrayPtr1->var_index should display data from holding_regs[500];
FltArrayPtr1->data should display data from holding_regs[501] and [502];
FltArrayPtr1->command should display data from holding_regs[503];

The actuality was:

FltArrayPtr1->var_index displayed data from holding_regs[500];
FltArrayPtr1->data displayed data from holding_regs[502] and [503];
FltArrayPtr1->command display data from holding_regs[504];

Basically, what ever I did, including following the examples given here, I could not set the pointers to point to the appropriate addresses – they always pointed 32bits/4bytes apart.

Then I found this article: http://www.grok2.com/structure_packing.html

Quote (talking about using attribute((packed))) :

“Note that this doesn’t seem to work right if you try to combine the typedef and the struct definition or if you combine variable declarations with the structure definition.”

So I changed my structure definitions into:

struct FltArrayType {
WORD16 var_index;
float data;
WORD16 command;
} attribute ((packed));

typedef struct FltArrayType FltArrayType;

FltArrayType *FltArrayPtr1;

Now this did not solve the problem completely: variables defined as FltArrayType worked, but pointers of that type still did not (very strange).

The GNU toolkit mentions “#pragma align X” which does not work, and also the compiler switch “-mstructure-size-boundary=X” nor ““-structure-size-boundary=X” where X is actually in bits.

The thing that finally set things straight was discovering “-fpack-struct”. Just open your “make” file and set the compiler options for both C and C++ files to:

APP_C_FLAGS=-fpack-struct
APP_CC_FLAGS=-fpack-struct

This along with attribute ((packed)) did fix all the problems that I had with both pointers and structures.

Hope this helps.