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

Started by
16 comments, last by silverphyre673 18 years, 10 months ago
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!
my siteGenius is 1% inspiration and 99% perspiration
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]
moe.ron
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.
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.
my siteGenius is 1% inspiration and 99% perspiration
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.

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!
my siteGenius is 1% inspiration and 99% perspiration
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.
I'll try that, thanks! My solution was pretty dang ugly :)
my siteGenius is 1% inspiration and 99% perspiration
the endian won't and doesn't matter
Quote:Original post by Anonymous Poster
the 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.
my siteGenius is 1% inspiration and 99% perspiration

This topic is closed to new replies.

Advertisement