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


当前回答

这是未经测试的,但在我看来,这应该是可行的。因为在小端序上是0x01,在大端序上是0x00。

bool runtimeIsLittleEndian(void)
{
    volatile uint16_t i=1;
    return ((uint8_t*)&i)[0]==0x01; // 0x01=little, 0x00=big
}

其他回答

请看这篇文章:

这里有一些代码来确定是什么 您的机器类型 Int num = 1; If (*(char *)&num == 1) { printf (" \ nLittle-Endian \ n "); } 其他的 { printf(“大端\ n”); }

…记得不能用令我惊讶的是,没有人意识到编译器会简单地优化测试,并将一个固定的结果作为返回值。这使得前面答案中的所有代码示例实际上都是无用的。

唯一会返回的是编译时的字节序!是的,我在之前的回答中测试了所有的例子。下面是一个使用Microsoft Visual c++ 9.0 (Visual Studio 2008)的示例。

纯C代码

int32 DNA_GetEndianness(void)
{
    union
    {
        uint8  c[4];
        uint32 i;
    } u;

    u.i = 0x01020304;

    if (0x04 == u.c[0])
        return DNA_ENDIAN_LITTLE;
    else if (0x01 == u.c[0])
        return DNA_ENDIAN_BIG;
    else
        return DNA_ENDIAN_UNKNOWN;
}

拆卸

PUBLIC    _DNA_GetEndianness
; Function compile flags: /Ogtpy
; File c:\development\dna\source\libraries\dna\endian.c
;    COMDAT _DNA_GetEndianness
_TEXT    SEGMENT
_DNA_GetEndianness PROC                    ; COMDAT

; 11   :     union
; 12   :     {
; 13   :         uint8  c[4];
; 14   :         uint32 i;
; 15   :     } u;
; 16   :
; 17   :     u.i = 1;
; 18   :
; 19   :     if (1 == u.c[0])
; 20   :         return DNA_ENDIAN_LITTLE;

    mov    eax, 1

; 21   :     else if (1 == u.c[3])
; 22   :         return DNA_ENDIAN_BIG;
; 23   :     else
; 24   :        return DNA_ENDIAN_UNKNOWN;
; 25   : }

    ret
_DNA_GetEndianness ENDP
END

也许可以为这个函数关闭任何编译时优化,但我不知道。否则,也许可以在汇编中硬编码,尽管那是不可移植的。即使这样,这个也可能被优化掉。这让我觉得我需要一些非常蹩脚的汇编器,为所有现有的cpu /指令集实现相同的代码,以及....不要紧。

此外,这里有人说,字节序在运行时不会改变。错了。现在有双端机器。它们的字节顺序在执行期间可以变化。而且,不仅有小端和大端,还有其他端。

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

例如;如果我们看看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打印出所有内置宏。)

参见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;
} 
bool isBigEndian()
{
    static const uint16_t m_endianCheck(0x00ff);
    return ( *((const uint8_t*)&m_endianCheck) == 0x0); 
}