"Henryk" <he************@gmx.de> wrote in news:1138106524.148895.293440
@g49g2000cwa.googlegroups.com:
Ok, that is new to me.
We have Sparc Leons inhouse. But it is too long ago that I worked with
to remember...
Just for my interest:
Could you give some more explanation why it would crash? Must an
integer value 2- or 4-byte aligned in memory? What about derefencing
the pointer back to char? Are there any alignment constraints then?
What about 1-byte packed structures?
As I recall, due to the instruction set on the processor, it can't
load/store an int-sized chunk of memory into a register from an unaligned
memory address.
So, with the example:
char buffer[1024];
*(reinterpret_cast<int *>(&buffer[1])) = 2;
The compiler may emit the machine code to load 2 into a register, then
attempts to store the register into the memory address &buffer[1]. The
hardware doesn't allow it, so the CPU generates a trap. This ends up
manifesting itself as a bus error in your program, and your program
crashes.
Accessing an int inside a 1-byte packed structure isn't an issue since
the compiler can examine your int access and realize that since it is
accessing the int from an unaligned address it will emit the machine code
to do the extra memory accesses (in order to comply with the aligned
memory access rules) to compose the int. So if you had (assuming
whatever compiler magic to make it 1-byte aligned):
struct st
{
char ch;
int anInt;
};
st stVar;
char * overlay = reinterpret_cast<st *>(&stVar);
In the example above it reads the 4 bytes starting at &overlay[0] into a
register, left shifts it 8 to throw away the 1st byte, then load the byte
at &overlay[4] and bitwise-or it with the working register to finally get
the complete int. Note that &stVar is by definition correctly aligned
for an object of type st.
To bring this discussion back to the Standard realm (from Sparc-
specific), the original code has undefined behaviour because you're
casting a pointer between unrelated types (and not void*).
What does work:
char buffer[1024];
int someInt(2);
memcpy(&buffer[1], &someInt, sizeof(someInt));
memcpy has to be able to deal with unaligned memory copies, so this would
work. (Exactly how it works is the problem of the compiler implementor,
as well as any sort of optimizations)