Misaligned storage

If you have a simple question and just want an answer.
Redeye
XCore Addict
Posts: 131
Joined: Wed Aug 03, 2011 9:13 am

Misaligned storage

Post by Redeye »

I'm moving some code over from v13 tools to v14.2. One feature I relied upon pretty heavily in this code was misaligned storage so that I could use functions like this :

Code: Select all

static unsigned int getObjectData(unsigned char *pchData, dataStruct *data)
{
	((int*)pchData)[0] = data->param1;
	((unsigned int*)pchData)[1] = data->param2;
	((unsigned int*)pchData)[2] = data->param3;
	((unsigned int*)pchData)[3] = data->param4;
	((unsigned int*)pchData)[4] = data->param5;
	return (5 * sizeof(unsigned int));
}
When I compiled this on v13 tools the disassembly shows that the actual storage was done with a __misaligned_store function which the compiler has obviously worked out is needed. However, compiling the same code on v14 tools doesn't do this, but I need it to otherwise I get an ET_LOAD_STORE exception thrown every time I try and store to a misaligned address.

Is there a way to force the compiler to treat the input pointer I'm writing to as misaligned like the v13 tools did? Speed isn't a big issue here - I know it's a lot slower than an aligned storage.
henk
Verified
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi Redeye,

Yes, casting from (char*) to (int *) is not guaranteed to end well.

I think memcpy() should do the trick? Either six calls, or first store all in an array of six ints and then call one memcpy() to store it in an unaligned character array?

Cheers,
Henk
Redeye
XCore Addict
Posts: 131
Joined: Wed Aug 03, 2011 9:13 am

Post by Redeye »

Thanks Henk,

Yes, that's probably the best way to deal with it. Though I suppose the smarter way to deal with it is to make sure the input pointer is word aligned.

I'm curious why this behaviour has changed between v13.2 and v14? This is identical code which is handled differently and crashes in v14 but runs fine in v13.2.
henk
Verified
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi,

At a guess - if you never use any knowledge about alignment, then all assignments from int* to int* have to be done through a mechanism that tests for alignment; making them all inefficient. I think the C standard says that one shall not case from char* to int* for that reason; always cast the other way. Ie, first make the memory int aligned, and then cast int* to char*?

Cheers,
Henk