tags:

views:

112

answers:

4

I was wondering if it's possible to emulate a big-endian behavior, for testing purpose?

via either windows or linux , mingw or gcc. Here's a sample of code which I would like the emulation to return big endian:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <limits.h>
#if CHAR_BIT != 8
#error "Unsupported char size for detecting endianness"
#endif

int main (void)
{
  short int word = 0x0001;
  char *byte = (char *) &word;
  if (byte[0]) printf("little endian");
  else printf("big endian");
  return 0;
}
+2  A: 

Why would you want to detect the endianness of your platform at run-time? When you go to compile, the endian mode is known. Your code will do what you expect it to... assuming that a short int is 2 bytes on the target platform. To avoid this hangup, you'd be better off looking at the last byte. (byte[sizeof(short int) - 1])

Here's a more detailed requirement: I have a util which stores data to a file. the data respects the native endianness of the local environment. Now I want this data to be valid under a different environment, which means it needs to 'adjust' itself via the indicator of the original environment - I hope I make sense?
Doori Bar
Best practices, in cases like this, use a single endianness for the file format, regardless of the architecture of the writer. There are methods you will find useful to help with this: htons, htonl, ntohl, ntohs. ([host|network]to[host|network][short|long]) htons will take a short and convert it to big endian - regardless of the native local endianness. ntohl will take a big endian long and convert it to your local byte order. Love these methods. They are your friends.
There are a few file formats that include endianness in their header and have libraries capable of translating to or at least from either endianness. It's work to do, though.
nategoose
Well you're kind of butchering my goal! :) ... I want to learn this approach, even so it would be easier to adjust all to a fixed endianness.
Doori Bar
A: 

If you really want to do this then you can use an Intel Mac and build for both x86 and ppc. The ppc executable will run via Rosetta emulation and will be big endian, whereas the native x86 build will of course be little endian.

Paul R
Intel Mac is a hardware?
Doori Bar
@Doori: yes, it's a Mac with an Intel CPU (as opposed to older Macs, which have IBM/Motorola PowerPC CPUs)
Paul R
@Paul R: Any chance you know of a software-based solution?
Doori Bar
Yep, QEMU for example. See my answer.
Luther Blissett
+2  A: 

You can throw a bunch of hton* (Host TO Network) and ntoh* (Network TO Host) calls in there between all of your different uses. Network endian is Big Endian.

16 bit: htons = Host TO Network Short ntohs = Network TO Host Short

32 bit: htonl = Host TO Network Long ntohl = Network to Host Long

Really both host to network and network to host are the same because the same swapping happens either way.

They are generally implemented as macros and will be no-ops on platforms that use big endian.

They live in:

#include <arpa/inet.h> 

Which is generally available.

You could also make use of <endian.h> if your libraries have it. With gcc this requires -D_BSD_SOURCE

On Unix, BSD, and Linux try: man htons man endian man byteorder

nategoose
I was hoping for a "cleaner" solution... emulation which I don't actively play a role creating. (for a more strict validation purpose)
Doori Bar
`int output_32(FILE * f, uint32_t x) { if (io_endian != local_endian ) { x = endian_swap32(x); } return fwrite( }`
nategoose
+1  A: 

You can't switch endianes for testing purposes or anything like that. What you can do is, to install an emulator for a big-endian architecture and compile your program for the emulator. Here's one way, under:

http://people.debian.org/~aurel32/qemu/

are Debian disk images for all kinds of QEMU supported architectures. mips, sparc and arm are big-endian (do not download anything ending with -el). I'm using Debian Lenny for MIPS ( http://people.debian.org/~aurel32/qemu/mips/ ). Install QEMU for your platform, then follow the instructions on the MIPS-page to download a image and kernel file.

Now you can boot into a Debian 5 for MIPS right from your console. Login to you virtual machine, become super user (the password is "root") and install the C-compiler:

debian-mips:~# su -
debian-mips:~# apt-get update
debian-mips:~# apt-get install gcc

fire up an editor and enter your program:

debian-mips:~# pico foo.c
debian-mips:~# gcc foo.c
debian-mips:~# ./a.out
big endian
Luther Blissett
Thanks for your answer, I haven't actually set-it-up just of yet, but I suppose it should answer my needs.
Doori Bar