Messages in this thread | | | From | Ralf Baechle <> | Subject | Re: Off-topic | Date | Thu, 6 Mar 1997 16:06:39 +0100 (MET) |
| |
> Beware - both __attribute__((packed)) and this method don't account > for hardware enforced alignment. If it is ever compiled on a system > that requires 8-byte alignment for a struct in_addr (a 4-byte entity) > it will bomb. I don't know if there is such hardware, but I have > already got bus errors on an HP using this technique on a misaligned > short (with the same program). A way around that is something like > > #define xx(s) ((((s)->buf[5])<<8)+(s)->buf[6])
__attribute__((packed)) _does_ account for hardware enforced alignment. Cite from the GCC man page:
The `packed' attribute specifies that a variable or structure field should have the smallest possible alignment--one byte for a variable, and one bit for a field, unless you specify a larger value with the `aligned' attribute.
While this does not influence the code generation on the i386 family or 68020 and bigger it does so for RISC CPUs, like Alpha or MIPS. This allows a nice portable implementation of the stuff in <asm/unaligned.h>:
#define get_unaligned(ptr) \ ({ \ struct __unal { \ __typeof__(*(ptr)) __x __attribute__((packed)); \ }; \ \ ((struct __unal *)(ptr))->__x; \ })
#define put_unaligned(ptr,val) \ ({ \ struct __unal { \ __typeof__(*(ptr)) __x __attribute__((packed)); \ }; \ \ ((struct __unal *)(ptr))->__x = (val); \ })
The bad thing is that at least some code generators perform pretty bad on these functions. For example GCC for Linux/MIPS targets makes perfect code from the above macros when accessing 32bit values but the code is really bad when accessing other quantities.
Ralf
| |