__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