Re: Off-topic

Ralf Baechle (ralf@Julia.DE)
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.