• Advertisement

I need someone to check if my program works on big-endian (Mac)

This topic is 4640 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I've been working on a hiscore system. It saves the hiscores to a binary file using a format and process I made myself. It tries to take into account both big and little endian systems. It works fine on my PC, which is little endian. I was hoping to get someone with a big-endian system (like a Mac) to test it out and make sure it works. If possible, please download it and test it out. You should just be able to put all the files together in a project using your favorite IDE or into a makefile for make, and compile them. They don't have any windows-only code. Thanks a lot, I appreciate it!

Share this post

Share on other sites
Advertisement
I have a windows machine, but I still have a couple suggestions. I don't think that code would work quite the way you think it would.

// always specify the sign of a char in these cases...some systems have // different defaultschar * ReverseByteOrder( const char * bytes ){    // whats this for?    char swap;    // what if bytes isn't null terminated? Or what if its terminated too early?    unsigned int length = std::strlen(bytes);         //  this points at one byte?    char * ret = new char[1];    // going out of bounds here    std::strcpy(ret, bytes);        for ( unsigned int i = 0, j = length-1; i < length; ++i, --j )    {                  ret = bytes[j];    }    return ret;}

Here's some changes I think would help you, this still isn't the optimal solution, but its the first thing that popped into my head
#include <iostream>#include <bitset>#include <exception>#include <climits>using std::bitset;using std::cout;using std::endl;using std::cerr;void * ReverseByteOrder(const void *pValue, const std::size_t numBytes){	if( 0 == pValue ) throw(std::exception(__FUNCTION__));	std::size_t i, j = numBytes-1;	const unsigned char *pData	= reinterpret_cast<const unsigned char*>(pValue);		 	unsigned char *pRetVal		= new unsigned char[numBytes];		for(i=0; i < numBytes; ++i, --j )		pRetVal = pData[j];	return(pRetVal);}int main(){		unsigned int before = 1, *pAfter = NULL;   	std::bitset<sizeof(int) * CHAR_BIT> b;   	try{		b = before;		cout << "Before swap\t" << b << endl;    			pAfter = (unsigned int*)ReverseByteOrder( &before, sizeof(before));            		b = *pAfter;		cout << "After swap\t" << b << endl;	}	catch(std::exception &e)	{		cerr << e.what() << endl;	}	catch(...)	{		cerr << "An unknown exception has occurred" << endl;	}      delete [] pAfter;	return(0);}

[EDIT]
Odd, well if it works it works I guess.. =) I could have sworn you should have been going out of bounds in a couple of spots there...
[/EDIT]

[Edited by - moeron on June 10, 2005 10:13:26 AM]

Share this post

Share on other sites
Hello,

I didn't look at your code, sorry. Here is the output on a 32-bit big endian machine (G4 PPC):

Mary has 1904 points.
Ben has 18 points.
John has 18 points.
Bip has 9 points.
Jeremy has 8 points.
Bob has 8 points.

Hope this helps.

Share this post

Share on other sites
Sweet! Guess it works. Anyone else give it a try? I would have rated you up anonymous, but you are anonymous :) ++rate for moeron, though. I appreciate it.

Share this post

Share on other sites
I couldn't get hiscoresystem.cpp to compile, got the following warnings and errors from g++:

hiscoresystem.cpp: In member function bool HiscoreSystem::Load()':
hiscoresystem.cpp:153: warning: comparison between signed and unsigned integer
expressions
hiscoresystem.cpp:173: error: type specifier omitted for parameter score'
hiscoresystem.cpp:174: error: no matching function for call to 
std::vector<Hiscore, std::allocator<Hiscore> >::push_back(Hiscore
(&)(std::basic_string<char, std::char_traits<char>, std::allocator<char> >))
'
/usr/include/c++/3.3.2/bits/stl_vector.h:596: error: candidates are: void
std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Hiscore, _Alloc
= std::allocator<Hiscore>]

Maybe i'm forgetting something, i'll come back and look at it when I get the chance.

Share this post

Share on other sites
I've made some code changes - found one of the errors you mentioned. If you could re-download it, that would be great, because the line numbers have changed :) The original link should work fin.

I really appreciate you taking the time to do this, though. Thanks again!

Share this post

Share on other sites
Your code relies on having a null terminated byte string (unsigned int length = std::strlen(bytes);)

Try this, it's more type safe than your solution - you should declare this in an anonymous namesapce and have wrappers for it only for types that it makes sense to endian-swap:

template<class T>T& ReverseByteOrder(T& value){    unsigned char* ptr = reinterpret_cast<unsigned char*>(&value);    size_t index = 0;    for(;index<(sizeof(T)/2);++index)    {        std::swap(ptr[index],ptr[size - index -1]);    }    return value;}template<class T>T ReverseByteOrder_copy(const T& value){   T value_copy = value;   ReverseByteOrder(value_copy);   return value_copy;}I don't have access to the actual code I use right now, so I had to write this from memory, but hopefully you get the idea.

Share this post

Share on other sites
I'll try that, thanks! My solution was pretty dang ugly :)

Share this post

Share on other sites
the endian won't and doesn't matter

Share this post

Share on other sites
Quote:
 Original post by Anonymous Posterthe endian won't and doesn't matter

Why not? I posted something on this a while ago and everyone told me it would. Anyways, I tried this:

entries_to_write = ReverseByteOrder_copy<int>(entries_to_write);

and similar on all the lines where I needed to reverse the byte order (changing <int> to <char*> when neccessary), but it gave me a bunch of linker errors, like this for example:

[Linker error] undefined reference to int ReverseByteOrder<int>(int const&)'

I can't think of how I'm supposed to change the statement so it will work. Can you give me an example? Thanks.

Share this post

Share on other sites
Quote:
 Original post by Anonymous Posterthe endian won't and doesn't matter

Unless you transfer the file to another comp, with another endianess.. I think anyway.. :p

Share this post

Share on other sites
Endian-ness matters the most when networking. And there are functions to convert to network byteorder and host byteorder. So it shouldn't be a problem.

Share this post

Share on other sites
Ok I got it built on a G3 running at 233mhz (yeah, it's an old computer) on OS 10.2.8

Output of first run through the program:
ERROR: Load Failed!
1: Jack has 32 points.

Output 2:
1: Jack has 32 points.
2: Jane has 18 points

3rd time running it:
1: Jack has 32 points.
2: Jane has 18 points.
3: Jerry has 3 points.

4th time:
1: Jack has 32 points.
2: Jane has 18 points.
3: Jerry has 3 points.
4: Jerry has 3 points.

5th time:
1: Bobby has 39 points.
2: Jack has 32 points.
3: Jane has 18 points.
4: Jerry has 3 points.
5: Jerry has 3 points.

Wish I could help fix it, but my knowledge of getting endian stuff to work is a bit lacking.

Have you ever considered using a text file? It would mean not having to worry about the endian issue here. If you wanted you could compress the high scores or make up an encryption algorithm (it's not like you're protecting credit card numbers here, so if was broken it wouldn't matter) to make it a little harder for user to cheat.

Share this post

Share on other sites
Forgot to mention I got these warnings compiling it:
hiscoresystem.cpp: In member function bool HiscoreSystem::Load()':
hiscoresystem.cpp:156: warning: comparison between signed and unsigned integer
expressions

endianfunctions.cpp: In function char* ReverseByteOrder(const char*)':
endianfunctions.cpp:11: warning: unused variable char swap'

Also just tested in on a x86 linux box and got pretty much the same result

Also, to make it easier for someone else to test it OS X or linux here's a Makefile:
all: hiscorehiscore: main.o hiscore.o hiscoresystem.o endianfunctions.o	g++ -Wall -o hiscore main.o hiscore.o hiscoresystem.o endianfunctions.omain.o: main.cpp	g++ -Wall -c main.cpphiscore.o: hiscore.cpp hiscore.h	g++ -Wall -c hiscore.cpphiscoresystem.o: hiscoresystem.cpp hiscoresystem.h	g++ -Wall -c hiscoresystem.cppendianfunctions.o:	g++ -Wall -c endianfunctions.cppclean:	rm *.o hiscore`

just remember to name the file Makefile
put it in the same directory as the code
go to the directory in the terminal
type make

Share this post

Share on other sites
Well... I guess nobody is going to be transferring their hiscore file from a max to their PC :)

I think I'll just take it out. Thanks for your help, everyone!

Share this post

Share on other sites
Quote:
 Original post by silverphyre673Well... I guess nobody is going to be transferring their hiscore file from a max to their PC :)I think I'll just take it out. Thanks for your help, everyone!

I got the same problems on an x86 box running linux (so it's probably not an endian thing). I haven't had the time to look through your source yet.

I compiled your code with g++, is there a chance that in your code you're doing something that in standard c++ is undefined, which works with the microsoft compilers, but since it is undefined behaves differently in the GNU compilers?

I'll take a look around when I get the chance. Also, you might want to ask the same question in the forums at www.idevgames.com. There are many more mac game developers there than here.

Share this post

Share on other sites
I just tried it on a PowerBook G4 (1.6 GHz) with MacOSX 10.4.1. Anyway, it really doesn't work so well. Same issues as Will F...but I am sure you could have guessed that.

Share this post

Share on other sites
I'm using dev-cpp with mingw. I just took out the endian stuff, but haven't reloaded it. At some point tonight (when I'm done studying for finals tomorrow) I will try it on my linux box w/ g++. Thanks for all your help!

Share this post

Share on other sites

• Advertisement
• Advertisement
• Popular Tags

• Advertisement
• Popular Now

• 45
• 11
• 17
• 11
• 13
• Advertisement