是否有一种编程方法来检测您使用的是大端序还是小端序体系结构?我需要能够编写将在英特尔或PPC系统上执行的代码,并使用完全相同的代码(即,没有条件编译)。


当前回答

我会这样做:

bool isBigEndian() {
    static unsigned long x(1);
    static bool result(reinterpret_cast<unsigned char*>(&x)[0] == 0);
    return result;
}

沿着这些思路,您将得到一个只进行一次计算的省时函数。

其他回答

参见Endianness - c级代码说明。

// assuming target architecture is 32-bit = 4-Bytes
enum ENDIANNESS{ LITTLEENDIAN , BIGENDIAN , UNHANDLE };


ENDIANNESS CheckArchEndianalityV1( void )
{
    int Endian = 0x00000001; // assuming target architecture is 32-bit    

    // as Endian = 0x00000001 so MSB (Most Significant Byte) = 0x00 and LSB (Least     Significant Byte) = 0x01
    // casting down to a single byte value LSB discarding higher bytes    

    return (*(char *) &Endian == 0x01) ? LITTLEENDIAN : BIGENDIAN;
} 

正如前面的答案所述,使用工会技巧。

但是上面建议的方法也存在一些问题。最值得注意的是,对于大多数架构来说,未对齐的内存访问是出了名的慢,一些编译器甚至根本无法识别这样的常量谓词,除非字对齐。

因为仅仅是端序测试很无聊,这里有一个(模板)函数,它将根据您的规范翻转输入/输出的任意整数,而不考虑主机架构。

#include <stdint.h>

#define BIG_ENDIAN 1
#define LITTLE_ENDIAN 0

template <typename T>
T endian(T w, uint32_t endian)
{
    // This gets optimized out into if (endian == host_endian) return w;
    union { uint64_t quad; uint32_t islittle; } t;
    t.quad = 1;
    if (t.islittle ^ endian) return w;
    T r = 0;

    // Decent compilers will unroll this (GCC)
    // or even convert straight into single bswap (Clang)
    for (int i = 0; i < sizeof(r); i++) {
        r <<= 8;
        r |= w & 0xff;
        w >>= 8;
    }
    return r;
};

用法:

要将给定的端序转换为主机,请使用:

Host = endian(source, endian_of_source)

要将主机端序转换为给定端序,请使用:

输出= endian(hostsource, endian_you_want_to_output)

生成的代码与在Clang上编写手动程序集一样快,在GCC上稍微慢一点(展开&,<<,>>,|每个字节),但仍然不错。

这通常在编译时(特别是出于性能原因)通过使用编译器提供的头文件或创建自己的头文件来完成。在Linux上,你有头文件“/usr/include/ endan .h”。

我很惊讶没有人提到预处理器默认定义的宏。但这取决于你的平台;它们比你自己写尾票要干净得多。

例如;如果我们看看GCC定义的内置宏(在x86-64机器上):

:| gcc -dM -E -x c - | grep -i endian

#define __LITTLE_ENDIAN__ 1

在PPC机器上,我得到:

:| gcc -dM -E -x c - | grep -i endian

#define __BIG_ENDIAN__ 1
#define _BIG_ENDIAN 1

(The:| gcc - dm - e -x c - magic打印出所有内置宏。)

你也可以通过预处理器使用Boost头文件来做到这一点,这可以在Boost endian中找到。