Endian-ness
Alright, I'm finally taking the plunge and making a universal binary. All I really need to do is swap the bytes when loading the levels, since I'm not using any textures or anything.
Now, the way I read an int (or a float) from a file already is to call this function:
First off, is it stupid to read the int as a succession of chars?
Secondly, it seems like if I just put in some test to see which architecture I'm on, I could just run the for loop the other way, and get the right result, without any speed hit for byte swapping. But Apple's docs recommend against using the ___BIG_ENDIAN___ macros, which I imagine are what I use to test which architecture I'm on. Is running the for loop backwards on Intel an advisable way of going? (And is doing it this way advisable on either platform?)
Now, the way I read an int (or a float) from a file already is to call this function:
Code:
static Boolean Read(int &i)
{
for(unsigned int j=0;j<sizeof(int);j++)
{
inChar=fgetc(infile);
if (inChar==EOF)
return false;
*( ( (char *) &i)+j)=inChar;
}
return true;
}First off, is it stupid to read the int as a succession of chars?
Secondly, it seems like if I just put in some test to see which architecture I'm on, I could just run the for loop the other way, and get the right result, without any speed hit for byte swapping. But Apple's docs recommend against using the ___BIG_ENDIAN___ macros, which I imagine are what I use to test which architecture I'm on. Is running the for loop backwards on Intel an advisable way of going? (And is doing it this way advisable on either platform?)
ia3n_g Wrote:First off, is it stupid to read the int as a succession of chars?Yep, considering there's a built-in way to read them:
Code:
int blah;
fread(&blah, 4, 1, infile);
So should I use fread and then one of the CF swap functions?
Yeah, that's fine.
ia3n_g Wrote:But Apple's docs recommend against using the ___BIG_ENDIAN___ macros)
They do? Where, if I may ask?
You should always used fixed-size types when doing I/O. There are a standard set in <stdint.h> called uint32_t and so forth.
What are OSReadLittleInt16 and OSWriteLittleInt16? I know I'd need the 32 bit version if they are relevant. I've seen them mentioned but I can't find documentation on them. Are they for file I/O?
OneSadCookie Wrote:They do? Where, if I may ask?
In "Guidelines for Swapping Bytes" it says:
"Use the __BIG_ENDIAN__ and __LITTLE_ENDIAN__ macros only if you must."
http://developer.apple.com/documentation...3-CJBBHCFG
Granted I may be placing more emphasis on that than I'm meant to.
Weird 
The OS.. byte-swapping routines are in <libkern/OSByteOrder.h> ( /usr/include/libkern/OSByteOrder.h ). They were added in 10.4.

The OS.. byte-swapping routines are in <libkern/OSByteOrder.h> ( /usr/include/libkern/OSByteOrder.h ). They were added in 10.4.
I'm running 10.4, but I don't have the libkern folder.
And how do they differ from the CF byte swapping routines?
And how do they differ from the CF byte swapping routines?
Whoops, should have read "include", not "lib" (I've edited the post).
They differ from the CF ones in that they're different from the CF ones
They differ from the CF ones in that they're different from the CF ones
ia3n_g Wrote:In "Guidelines for Swapping Bytes" it says:That is indeed weird, so I decided to read a little further into it...
"Use the __BIG_ENDIAN__ and __LITTLE_ENDIAN__ macros only if you must."
http://developer.apple.com/documentation...3-CJBBHCFG
Granted I may be placing more emphasis on that than I'm meant to.
Here's another quote from that same document:
Quote:The C preprocessor has several predefined macros whose purpose is to indicate the type of system
and machine in use. If your code uses system-specific predefined macros, evaluate whether you really
need to use them. In most cases applications need to know the capabilities available on a computer
and not the specific system or machine on which the application is running. For example, if your
application needs to know whether it is running on a little-endian or big-endian microprocessor, you
should use the __BIG_ENDIAN__ or __LITTLE_ENDIAN__ macros or the Core Foundation function
CFByteOrderGetCurrent. Do not use the __i386__ and __ppc__ macros for this purpose.
Given this and all the other stuff I've read in code sample comments, and just common sense, I would say that the quote:
"Use the __BIG_ENDIAN__ and __LITTLE_ENDIAN__ macros only if you must."
Needs to be put in the context of the sentence following it as well:
"Do not use macros that check for a specific processor type, such as __i386__ and __ppc__."
Furthermore, I would guess that the first sentence was actually meant to be written:
"Use the __BIG_ENDIAN__ and __LITTLE_ENDIAN__ macros only, if you must."
(notice my addition of the comma) Heck, I think the `if you must.' part could have been left out in the first place. The bottom line is that you should use __BIG_ENDIAN__ and __LITTLE_ENDIAN__ when it makes sense to do so.
I think their point is that eg. OSSwapHostToBigInt32 compiles to nothing on a PowerPC machine anyway, so you shouldn't write
because it's exactly the same as
In terms of what the compiler generates.
I do think it's rather misleading, though!
Code:
#if defined(__LITTLE_ENDIAN__)
x = OSSwapHostToBigInt32(x);
#endifbecause it's exactly the same as
Code:
x = OSSwapHostToBigInt32(x);In terms of what the compiler generates.
I do think it's rather misleading, though!
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Confused with array-ness | Tobs_ | 4 | 2,944 |
Aug 12, 2007 05:37 PM Last Post: JeroMiya |
|
| Even *MORE* endian issues | Jones | 22 | 5,913 |
Aug 3, 2006 06:40 PM Last Post: Jones |
|
| Little Endian to Big Endian | Jones | 42 | 12,429 |
Jul 20, 2006 12:07 PM Last Post: Jones |
|

