Bytes alignement problem with arm-linux-gcc

Frederic Kwiatkowski stagedrt@gmail.com
Thu Feb 8 13:28:00 GMT 2007


Thanks for all this informations

As __attribute__ as no effect, I think i will use 4 unsigned char
instead of 1 unsigned long


With regards

Frederic

2007/2/8, John (Eljay) Love-Jensen <eljay@adobe.com>:
> Hi Frederic,
>
> Not a bug.
>
> Structures can add alignment padding bytes in between data members, and at the end of the structure, so the member variables abide by the alignment constraints of their data types.
>
> What is the alignment constraint of an unsigned long on your platform?  Probably 4.  Which means there are 3 padding bytes between t_paquet.NAMEDFIELD.error and t_paquet.NAMEDFIELD.entete; and 3 trailing pad bytes after t_paquet.NAMEDFIELD.data.  (You can use offsetof to easily see where those data members fall for alignment.)
>
> Because of those padding bytes, my "rule" is:  never use write/fread a structure as a block.  The issues are:
> 1) padding bytes (which can vary from platform-to-platform, and even from compiler-to-compiler)
> 2) endian, for anything other than {signed|unsigned|nonsigned} char
> 3) floating point, which may-or-may-not be in IEEE 754, and endian issues too
> 4) bool ... 1 byte? 4 bytes?  something else?
> 5) int ... 2 bytes? 4 bytes? something else?
> 6) long ... 4 bytes? 8 bytes? something else?
> 7) long long ... 4 bytes? 8 bytes? 16 bytes? something else?
> 8) float ... probably 32-bit
> 9) double ... probably 64-bit
> 10) long double ... 64-bit? 80-bit? 128-bit? something else?
> 11) pointer ... YIKES!  don't save pointers!  Save some sort of "id" or "index" instead.
>
> Because I used to deal with IP packets, I make a record structure that consists of nothing but byte (typedef char byte) fields, populate the struct or class to the canonical byte record struct using network-byte-order (big endian).  I'd repackage the class/struct into a "over the wire" record struct, and write it as a single block packet (because I'd disable the Nagle's algorithm for legit reasons, which would otherwise act as a accumulation buffer for me).
>
> For canonical sizes in my canonical data typed structs & classes, I'm one of the Happy Campers to have C99's <stdint.h>, although I regularly use it for C++ (naughty, naughty).  I hope C++ WG blesses <cstdint> and <cinttypes> soon.
>
> Others would probably only be concerned with file I/O, so would rely on the buffering of the fstream or FILE* facilities.  In that case, no need to have a record struct -- just have a serialize / deserialize routine to write / read the class object or struct.
>
> Another solution is something like XML (e.g., SOAP), but there is additional overhead for packaging and parsing the XML which may-or-may-not be a concern depending on what is needed in a file store or over-the-wire packet.
>
> > How can this problem can be resolved?
>
> Don't use a union.  It (probably) isn't doing what you want it to do.
>
> > Is there a specific compilation option for alignement problems?
>
> Read The Fine Manual.
>
> http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
>
> Caution: in my experience, if your are fiddling with attributes to bludgeon a union to have the layout you want, it's quite likely that you are trying really hard to shoot yourself in the foot.  On top of that, there are very, very few legit reasons to ever use a union (ditto with bit fields) -- if you don't know what those legit reasons are, then it's a good bet that a union (or bit fields) is not the facility you should be using.
>
> HTH,
> --Eljay
>



More information about the Gcc-help mailing list