3

So I have some audio processing dlls made and I was wondering how I can determine endianness of the processor. I know that Visual Studio defines some processor macros but I can't find a complete list of them. I would prefer this to be a compile time check because I'm probably going to compile this for different processors.

EDIT: Also I am targeting windows. I've heard that Windows only uses Little Endian, is that true?

Caleb Merchant
  • 289
  • 1
  • 5
  • 16
  • Windows NT ran on MIPS, DEC Alpha and PowerPC CPU:s, which are all Big Endian. However, support for these CPU:s where dropped in Windows 2000. So unless you target Windows NT you can safely assume that the system is Litte Endian. – Pibben Feb 09 '21 at 08:28
  • I hear that Windows only run on little endian machines. But it is amazing that the formula: bigEndian = 'x\0\0\0' & 'x' littleEndian = '\0\0\0x' & 'x' does not work. Atleast for 64 bit windows. – user13947194 Aug 29 '21 at 13:56

3 Answers3

7

I found a way to determine the endianness using the C preprocessor.

Please be aware that I did not test this code on a big endian machine

It uses some defines of the registry value types [1].

REG_DWORD is defined there as the endianness of the architecture Windows is running on.

Add the _byteswap_TYPE functions to the mix and we can write a preprocessor definition [2].

#include <Windows.h>

#if REG_DWORD == REG_DWORD_LITTLE_ENDIAN
# define le_to_host_ulong(VAL) VAL
# define be_to_host_ulong(VAL) _byteswap_ulong(VAL)
# define le_to_host_ushort(VAL) VAL
# define be_to_host_ushort(VAL) _byteswap_ushort(VAL)
# define le_to_host_uint64(VAL) VAL
# define be_to_host_uint64(VAL) _byteswap_uint64(VAL)
#else
# define le_to_host_ulong(VAL) _byteswap_ulong(VAL)
# define be_to_host_ulong(VAL) VAL
# define le_to_host_ushort(VAL) _byteswap_ushort(VAL)
# define be_to_host_ushort(VAL) VAL
# define le_to_host_uint64(VAL) _byteswap_uint64(VAL)
# define be_to_host_uint64(VAL) VAL
#endif

[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx

[2] https://msdn.microsoft.com/en-us/library/a3140177.aspx

maarten
  • 336
  • 2
  • 10
  • This is totally incorrect. REG_DWORD and REG_DWORD_LITTLE_ENDIAN are constant defines for the Windows Registry API. That should be obvious by looking at the Windows header file. https://en.cppreference.com/w/cpp/types/endian – Marius Greuel May 17 '22 at 08:00
1

Visual Studio only provides preprocessor macros identifying the platform (eg. _WIN32, etc.). A complete list can be found here: https://msdn.microsoft.com/en-us/library/b0084kay.aspx. It unfortunately does not provide any to identify the endianness. From the platform target macros in that list, you must determine whether that platform is big or little endian. As stated in the answer to this question (Can I safely assume that Windows installations will always be little-endian?), Windows x86/x64 is always little endian.

However, there is no guarantee that future updates of Windows will not target big-endian processors, but in that case, this list will likely be updated. Also note that Visual Studio, with different compilers, currently targets non-Windows platforms which are big endian (Xbox 360, for example).

Community
  • 1
  • 1
MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
0

Consider this code:

const uint16_t endianness_check = 0x1234;
    const bool is_little_endian = (*reinterpret_cast<const uint8_t*>(&endianness_check) == 0x34);

or

#define IS_BIG_ENDIAN (*(WORD *)"\0\x2" == 0x200)
Ben
  • 69
  • 8