Endian. When do you care?

Started by
28 comments, last by griffin2000 17 years, 9 months ago
Really this comes down to: when do you actually care about the endian of something? I understand the difference of big and little endian, and that it affects what you save out to a file. If a system is big endian, and I need to read in from a file saved in little endian, what changes? If I save an int(32bit) then I should be concernerned. What about a float(32bit) or a char array(4*8bit)? ---- More background, if I have a Read function can I make it deal with endianness without making: Read_uint16_LE2BE Read_uint16_BE2LE ..ect and without having Read ( data*, size, bool_endian_sensitive );
Advertisement
int, yes. float, probably not. char array - not likely.
I only care about endian when working with networks.
Since I am only working on little endian platforms I don t care about it in conjunction with binary files.
If you have to port your code to a big endian platform once, you add some compilation flags and add some conversion functions in your io implementation for binary data (htonl,....)
http://www.8ung.at/basiror/theironcross.html
It mostly matters when saving to a file that you want to be able to load on a different platform or when sending data over a network. It matters for any data type larger than 1 byte - int, float, long, double, bool (on some platforms), etc.

Game Programming Blog: www.mattnewport.com/blog

Its the "atomic" types, that are greater than 1-byte in length, that matter..

So if I write on my PC

struct MyStruct{  char  name[32];  int   a;  short b;  float c;};..MyStruct data;..fwrite(&data, sizeof(a), 1, myFile);


Then when I read from my Mac, Xbox360, PS3, etc. I data.name will be ok, but I must swap a, b, and c.

fread(&data, sizeof(MyStruct), 1, myFile);MYSWAPMACRO_32(&data.a);MYSWAPMACRO_16(&data.b);MYSWAPMACRO_32(&data.c);

Thanks.
So, for just about anything that is not 8bit I would need to have support to swap the bytes around.
But since the char arrays are unaffected by endian, I can't just make a system that says:
read ( void *data, size_t size ){size_t bytes_read = fread ( file, size,1, data );if ( bytes_read == 8 ) FixEndian64 ( data );if ( bytes_read == 4 ) FixEndian32 ( data );if ( bytes_read == 2 ) FixEndian16 ( data );}


I would actually have to leave the swapping to the next higher level, where the datatype is known?
Yes you have to know what data it is your reading to swap it correctly... So you could have your own ReadShort, ReadInt, etc. functions that do the appropriate swapping. But you could not just assume from the size of the read command (a read of 4 bytes could be of structure of two shorts or a single int etc..).

Edit... You could also rely on polymorphism, which could make you life a little easier...

e.g.

class MyReader{  bool Read(int *pVal) { ReadSwapped32(pVal,sizeof(int)); )  bool Read(short *pVal) { ReadSwapped16(pVal,sizeof(short)); )  bool Read(char *pData, size_t n);// No swapping..}reader.Read(myInt);reader.Read(myShort);reader.Read(myStr,32);
Well, thanks griffin,
I'm mimiking the fstream.read and fread functionality, and so have no connection to the data,
but at a higher level I will need endian correctness, so I will probably come up with a polymorphic endian utility class that can be used by the subsystems that need it.
you should also be aware that some casting that works on little-endian doesnt work at all on big endian-

typedef unsigned char byte;int i = 255;byte c = *((byte*)&i);cout << c;


This will output 255 on a little endian system, and 0 on a big endian system.

If you need to do stuff like this, use a reinterpret_cast instaed of the crappy C-style cast I've used here.
Allways question authority......unless you're on GameDev.net, then it will hurt your rating very badly so just shut the fuck up.
Quote:Original post by mattnewport
It mostly matters when saving to a file that you want to be able to load on a different platform or when sending data over a network. It matters for any data type larger than 1 byte - int, float, long, double, bool (on some platforms), etc.


Surely not float? Isn't it the same on all platforms with IEEE floating point?

This topic is closed to new replies.

Advertisement