structure to bytes

Technical questions regarding the XTC tools and programming with XMOS.
omega7
Active Member
Posts: 32
Joined: Thu Jun 03, 2010 12:16 pm

structure to bytes

Post by omega7 »

This is really straight forward, but i am looking for a compact solution converting an arbitrary datatype to stray bytes, as stored in memory.
Is it true then, that the order of declaring fields in a structure are exactly the byte order in memory? Should I take a certain 'byte alignment' into account?
Any theory and example is welcome!
Martin


richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

The layout of a structures is determined by the ABI. See the Tools developer guide. Fields will be stored in memory in the same order as they are declared but there may be padding added between structure members to make each member aligned. For example:

Code: Select all

struct s {
  char c;
  int x;
};
Will be laid out as a 1 byte char followed by 3 bytes of padding followed by a 4 byte integer.
User avatar
jonathan
Respected Member
Posts: 377
Joined: Thu Dec 10, 2009 6:07 pm

Post by jonathan »

richard wrote:The layout of a structures is determined by the ABI. See the Tools developer guide. Fields will be stored in memory in the same order as they are declared but there may be padding added between structure members to make each member aligned. For example:

Code: Select all

struct s {
  char c;
  int x;
};
Will be laid out as a 1 byte char followed by 3 bytes of padding followed by a 4 byte integer.
Just out of interest, reading this thread, how does...

Code: Select all

struct s {
  char c;
  int x;
  char d;
  int y;
  char e;
  int z;
  char f;
};
... get laid out? Is it different to how:

Code: Select all

struct s {
  char c;
  char d;
  char e;
  char f;
  int x;
  int y;
  int z;
};
... gets laid out?
Image
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

Yes, these will get laid out differently. The order of the fields is significant. The first example will have 3 bytes of padding after each char member and the second example will have no padding.
omega7
Active Member
Posts: 32
Joined: Thu Jun 03, 2010 12:16 pm

Post by omega7 »

Thanks for the advises! In the meantime I succeeded to convert my structure to bytes using reinterpretation:

Code: Select all

void CopyToFrameData(unsigned char frameData[], int &datalength, AcqData data)
{
	int size = sizeof(AcqData);

    for (int i=0;i<size;i++)
    {
    	frameData[i] = (data, char[])[i];
    }

	datalength = size;
} 
But, is there a way back? Convert an array of bytes into a structure, int,.... etc.?
Normally in C, I would use: *( (int*) &framedata[0])
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

In C the name of an array is a pointer to the first element of the array. So instead of "&framedata[0]" you only need "framedata".

I would be wary of casting pointers to byte arrays into pointers to integers and vice versa. Reason being that on different processor architectures the byte ordering of integers in memory is different. Big endian vs little endian. This may not matter in any one application on one processor type but if you ever want to run the code on a different machine, for testing purposes say, it may fail.

For similar reasons I would be wary of relying on the padding in structures. Some processors impose alignment restrictions. 16 bit words have to me on even addresses. 32 bit ints have to be 4 byte alingned etc. So just grabing a pointer into a structure and casting to what you think is there may not work on different architectures.

Better to ensure portability by explicitly shifting and masking things around to do the type conversions.

BUT if performance is really important you may have to use the simple casts. Macros that expand differently on little or big endian machines can help portability here.
omega7
Active Member
Posts: 32
Joined: Thu Jun 03, 2010 12:16 pm

Post by omega7 »

This reply is really fast! Thanks.

I was aware of the endians. Please say when I am wrong, but x86 and XMOS are both little endian processors aren't they?

For my project I have to decode binary frames from an UART into, at least int's. How would such a cast look like in XC?