是否有一种编程方法来检测您使用的是大端序还是小端序体系结构?我需要能够编写将在英特尔或PPC系统上执行的代码,并使用完全相同的代码(即,没有条件编译)。
当前回答
这个怎么样?
#include <cstdio>
int main()
{
unsigned int n = 1;
char *p = 0;
p = (char*)&n;
if (*p == 1)
std::printf("Little Endian\n");
else
if (*(p + sizeof(int) - 1) == 1)
std::printf("Big Endian\n");
else
std::printf("What the crap?\n");
return 0;
}
其他回答
c++20解决方案:
constexpr bool compare(auto const c, auto const ...a) noexcept
{
return [&]<auto ...I>(std::index_sequence<I...>) noexcept
{
return ((std::uint8_t(c >> 8 * I) == a) && ...);
}(std::make_index_sequence<sizeof...(a)>());
}
static constexpr auto is_big_endian_v{
compare(std::uint32_t(0x01234567), 0x01, 0x23, 0x45, 0x67)
};
static constexpr auto is_little_endian_v{
compare(std::uint32_t(0x01234567), 0x67, 0x45, 0x23, 0x01)
};
static constexpr auto is_pdp_endian_v{
compare(std::uint32_t(0x01234567), 0x23, 0x01, 0x67, 0x45)
};
这个任务可以更容易地完成,但是由于某种原因,<bit>头文件并不总是存在。这是一个演示。
正如Coriiander所指出的,这里的大部分(如果不是全部的话)代码将在编译时被优化掉,因此生成的二进制文件不会在运行时检查“字节顺序”。
据观察,给定的可执行文件不应该以两个不同的字节顺序运行,但我不知道是否总是这样,对我来说,在编译时检查似乎是一种hack。所以我编写了这个函数:
#include <stdint.h>
int* _BE = 0;
int is_big_endian() {
if (_BE == 0) {
uint16_t* teste = (uint16_t*)malloc(4);
*teste = (*teste & 0x01FE) | 0x0100;
uint8_t teste2 = ((uint8_t*) teste)[0];
free(teste);
_BE = (int*)malloc(sizeof(int));
*_BE = (0x01 == teste2);
}
return *_BE;
}
MinGW无法优化这段代码,尽管它确实优化了这里的其他代码。我相信这是因为我保留了分配在较小字节内存上的“随机”值(至少有7位),所以编译器无法知道这个随机值是什么,也不会优化函数。
我还对函数进行了编码,以便只执行一次检查,并为下一次测试存储返回值。
bool isBigEndian()
{
static const uint16_t m_endianCheck(0x00ff);
return ( *((const uint8_t*)&m_endianCheck) == 0x0);
}
我很惊讶没有人提到预处理器默认定义的宏。但这取决于你的平台;它们比你自己写尾票要干净得多。
例如;如果我们看看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打印出所有内置宏。)
要了解更多细节,你可能想要查看这篇codeproject文章Endianness的基本概念:
如何在运行时动态测试Endian类型? 正如《计算机》中解释的那样 动画FAQ,可以使用 下面的函数看看你的代码 是在小端还是大端运行 系统:崩溃 定义BIG_ENDIAN 0 #定义LITTLE_ENDIAN
int TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
return(byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}
这段代码将值0001h赋给a 16位整数。然后是char指针 第一次分配给点 的(最低有效)字节 整数值。的第一个字节 整数是0x01h,然后系统 是Little-Endian (0x01h在 最低或最不重要, 地址)。如果是0x00h,则 系统是大端的。