As pointed out in an answer to this question, the compiler (in this case gcc-4.1.2, yes it\'s old, no I can\'t change it) can replace struct assignments with memcpy where it
As far as I can tell, this is a compiler bug. i is allowed to alias &o.i according to the aliasing rules, since the types match and the compiler cannot prove that the address of o.i could not have been previously taken. And of course calling memcpy with overlapping (or same) pointers invokes UB.
By the way note that, in your example, o->i is nonsense. You meant o.i I think...