This is an old revision of the document!


Endian Template (C++)

Work with big endian and little endian types in C++ without ever calling an "endian swap" function

License

Download

Before downloading or using this product, make sure you understand and accept the terms of the license.

After downloading, make sure to follow the how to use instructions below; they're worth reading.

About

The Endian Template is a set of C++ template class and typedefs that allow you use little endian or big endian types, without having to write or concern yourself with "endian swap" functions, on any platform that supports at least the C++98 standard.

This provides a few benefits over other techniques:

  • Guaranteed endian correctness when using a typedef
  • No need to call "endian swap" functions
  • No need for "endian detection macros", as everything is determined at compile-time / run-time
  • Ability to wrap your own types with the provided templates

How to Use

Setup

  • First, copy the header tEndian.h into your project.
  • Next, include the header somewhere in your project or precompiled header if you use one.
  • You will also need to include assert.h and cstdint if they're not already included in your project
#include <assert.h>
#include <cstdint>
#include "tEndian.h"

Typedefs

You'll now have the following typedefs to use in your project:

  • leint16_t, leint32_t, leint64_t - Little endian signed types
  • leuint16_t, leuint32_t, leuint64_t - Little endian unsigned types
  • lefloat32_t, lefloat64_t - Little endian floating point types
  • beint16_t, beint32_t, beint64_t - Big endian signed types
  • beuint16_t, beuint32_t, beuint64_t - Big endian unsigned types
  • befloat32_t, befloat64_t - Big endian floating point types

The naming conventions are based on those in C++ standard library header cstdint; the only addition being a prefix of le or be to indicate little endian or big endian, respectively.

Templates

You'll also have the following template classes available for use in your project:

  • tLittleEndian<T> - Little endian template wrapper
  • tBigEndian<T> - Big endian template wrapper

With those template wrappers, you could in theory wrap your own types.

For instance, if you wanted to define a big endian version of size_t and short, and a little endian version long long, the following example code will achieve this:

typedef tBigEndian<size_t>       besize_t;
typedef tBigEndian<short>        beshort;
typedef tLittleEndian<long long> lelonglong;

You will also find a third template, tEndianBase<T>, however it's only meant to be used as a helper class from the other template classes, so I don't suggest you use it directly yourself.

Usage

When using the endian types, you can literally just drop them in to replace your current types, as long as you also remove any endian swapping functions you're calling.

There are three primary reasons I see someone using the Endian Template:

  1. You're writing an emulator / virtual machine
  2. You're writing a binary file format reading / writing library
  3. Converting data sent over a network

I'll cover these three use cases, but forgive me as I'll be very brief with each.

Emulator / Virtual Machine

Of course, depending on the machine type, memory itself will be stored as big or little endian. However, it's typically when you're loading memory into registers, then doing math on those registers, when endianness starts to matter.

That said, you could define each register as the proper endian type for the platform you're emulating, and you won't have to worry or remember about shifting memory one way or another after a math operation– it just gets stored correctly on it's own.

Binary file formats

Binary formats are compact but are a potential minefield when dealing with different CPU architectures. The Endian Template can help here too.

I used to love writing things like image decoders for formats like BMP and the like. For example, in a BMP file, the first two bytes are typically BM, but the next four bytes are "the size of the BMP file"– in little endian format.

If you read this data into an uint32_t, you're fine as long as you're on a little endian machine (like an x86-based PC.) Not so much if you end up running your code on a PowerPC CPU, which is big endian.

So take the guesswork out of the equation– read it into an leuint32_t instead and it'll always work, regardless of the architecture.

Sending data over a network

If you're familiar with Network Byte Order, you'll know that the functions htons, htonl, ntohl, ntohs are generally suggested to use before sending data over a network.

Since "Network Byte Order" is just "big endian"; instead you can now just define your data as beint32_t, beint16_t, or tBigEndian<unsigned short> and discard the conversion functions completely.

And regardless of the endian of computer's CPU, the code will always work.

Running the unit tests

The Endian Template comes with a unit test class, tEndianTests.cc, and three project files:

  • /project/win/EndianTests.sln - Visual Studio 2005, Windows console target
  • /project/mac/EndianTests.xcodeproject - Xcode 7 Mac OS console target
  • /project/ios/EndianTests.xcodeproject - Xcode 7 iOS console target

When running the unit test on Visual Studio, note you will first need to convert the solution to the latest version. You'll also need to put a breakpoint on the last line of the main function, as the console window containing the results of the test will close on exit.

When running the unit test on Mac or for iOS, the results of the test will be printed in Xcode's debug console, which is at the bottom right of Xcode's window.

Also, when running for iOS, you'll note that an app won't appear or launch in the simulator or on a device, as the tests are purely meant to display in the debug console.

(If you're curious, these project files were generated with Google GYP; the source project file is located in /project/common/EndianTests.gyp.)

Q & A

If you have a question not answered here, please feel free to contact me and ask.

No questions so far!

History

February 23, 2016

  • Added GitHub link to download section
  • First public release
  • Created project page
Print/export
QR Code
QR Code Endian Template (C++) (generated for current page)