On Aug 2, 2005, at 1:15 PM, Shaun Jackman wrote:
There is no padding. The structure is defined as
__attribute__((packed)) to explicitly remove the padding. The result
is that gcc knows the unaligned four byte member is at an offset of
two bytes from the base of the struct, but uses a four byte load at
the unaligned address of base+2. I don't expect...
p->unaligned = n;
... to work,
Actually, that works just fine, with:
typedef struct {
unsigned short int a;
unsigned int b;
} __attribute__((packed)) st;
void foo(st *s, int n)
{
s->b = n;
}
I get:
_foo:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
mov r3, r1, lsr #24
mov r2, r1, lsr #8
mov ip, r1, lsr #16
@ lr needed for prologue
strb r3, [r0, #5]
strb r2, [r0, #3]
strb ip, [r0, #4]
strb r1, [r0, #2]
mov pc, lr
but I definitely expect
memcpy(&p->unaligned, &n, sizeof p->unaligned);
to work.
Ah, I was having trouble getting it to fail for me... Now I can:
#include <memory.h>
typedef struct {
unsigned short int a;
unsigned int b;
} __attribute__((packed)) st;
void foo(st *s, int n)
{
memcpy(&s->b, &n, sizeof n);
}
_foo:
@ args = 0, pretend = 0, frame = 4
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
sub sp, sp, #4
@ lr needed for prologue
str r1, [r0, #2]
add sp, sp, #4
bx lr
Yes, this is a compiler bug in the expansion of memcpy, please file a
bug report. The solution is for the compiler to notice the memory
alignment of the destination and `do-the-right-thing' when it isn't
aligned.