memcpy to an unaligned address

Mike Stump mrs@apple.com
Tue Aug 2 20:29:00 GMT 2005


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.



More information about the Gcc mailing list