RVMDK v3.00a, Hello World sample for RealView compiler #pragma pack(1) unsigned char Buf[40]; int main (void) { *((short int *)&Buf[0]) = 0x77ff; *((int *)&Buf[2]) = 0x12345678; /* initialize the serial interface */ PINSEL0 = 0x00050000; U1LCR = 0x83; U1DLL = 97; U1LCR = 0x03; printf ("Hello World\n"); printf("%x %x %x %x \n", Buf[0],Buf[1],Buf[2],Buf[3]); } Hello World 78 56 34 12 ------------ The same thing is for CARM compiler 2.4, 2.5 What I am wrong ?
You must use -
*((__packed int *)&Buf[2]) = 0x12345678;
One common problem with this is typecasting. I had a "fun time" once (on an XA) finding that when typecastion a char to an int you did not "see" the alignment problem. so, as of the, it is a rule that nothing can be typecase "upwards" Erik
One common problem with this is typecasting. I had a "fun time" once (on an XA) finding that when typecastion a char to an int you did not "see" the alignment problem. typecasting is only way of saying to compiler how many bytes we copy to some place. I have never see any aligment problems due to typecasting. A lot of unix stuff use things like in subj(summary) as well as in intel sources
I have never see any aligment problems due to typecasting Then you've been lucky. Or, depending on your processor, you just haven't noticed. Some processors will run correctly, but slower, with misaligned accesses. Try this code on your processor of choice that requires alignment: U8 bytes[4]; U32 dest; ... dest = *(U32*)&bytes[0]; dest = *(U32*)&bytes[1]; dest = *(U32*)&bytes[2]; dest = *(U32*)&bytes[3]; and you'll see a misaligned access at some point. Without the typecast, the compiler could detect the misalignment. With the typecast, I've assured the compiler that everything is okay and that I know what I'm doing -- which, in this case, is the wrong thing in three out of four cases.
I think you missed Evegeny's point a bit because you understand a different thing under the term "typecast" than he does. U8 bytes[4]; U32 dest; ... dest = *(U32*)&bytes[0]; dest = *(U32*)&bytes[1]; dest = *(U32*)&bytes[2]; dest = *(U32*)&bytes[3]; [...] Without the typecast, the compiler could detect the misalignment. Not really. Without the casts, that snippet completely changes semantics. It becomes equivalent to four assignments of a char value to a U32 variable, like this:
U8 bytes[4]; U32 dest; ... dest = *(U32*)&bytes[0]; dest = *(U32*)&bytes[1]; dest = *(U32*)&bytes[2]; dest = *(U32*)&bytes[3];
dest = bytes[0]; dest = bytes[1]; dest = bytes[2]; dest = bytes[3];
then what about this one U8 bytes[4]; U32 dest; ... dest = (U32)&bytes[0]; dest = (U32)&bytes[1]; dest = (U32)&bytes[2]; dest = (U32)&bytes[3]; Erik
dest = (U32)&bytes[1]; This is equivalent to
dest = (U32)&bytes[1];
dest = (U32)(bytes + 1);
View all questions in Keil forum