我搜索了宏来确定机器上的字节顺序,但没有找到任何标准的处理器宏,但很多解决方案在运行时执行此操作。为什么我应该在运行时检测字节序?
如果我这样做:
#ifdef LITTLE_ENDIAN
inline int swap(int& x) {
// do swap anyhow
return swapped;
}
#elif BIG_ENDIAN
inline int& swap(int& x) { return x; }
#else
#error "some blabla"
#endif
int main() {
int x = 0x1234;
int y = swap(x);
return 0;
}
编译器只会生成一个函数。
但如果我这样做(参见预定义字节序 http://sourceforge.net/p/predef/wiki/Endianness/):
enum {
ENDIAN_UNKNOWN,
ENDIAN_BIG,
ENDIAN_LITTLE,
ENDIAN_BIG_WORD, /* Middle-endian, Honeywell 316 style */
ENDIAN_LITTLE_WORD /* Middle-endian, PDP-11 style */
};
int endianness(void)
{
uint8_t buffer[4];
buffer[0] = 0x00;
buffer[1] = 0x01;
buffer[2] = 0x02;
buffer[3] = 0x03;
switch (*((uint32_t *)buffer)) {
case 0x00010203: return ENDIAN_BIG;
case 0x03020100: return ENDIAN_LITTLE;
case 0x02030001: return ENDIAN_BIG_WORD;
case 0x01000302: return ENDIAN_LITTLE_WORD;
default: return ENDIAN_UNKNOWN;
}
int swap(int& x) {
switch(endianess()) {
case ENDIAN_BIG:
return x;
break;
case LITTLE_ENDIAN:
// do swap
return swapped;
break;
default:
// error blabla
}
// do swap anyhow
}
编译器生成检测代码。
我不明白,我为什么要这样做?
如果我有为小端机器编译的代码,则为小端机器生成整个代码,并且如果我尝试在大端机器上运行此类代码(在像arm这样的双端机器上)维基百科:双端 http://en.wikipedia.org/wiki/Endianness#Bi-endian_hardware)整个代码是为小端机器编译的。所以所有其他声明例如int也勒。
// compiled on little endian
uint32_t 0x1234; // 0x1234 constant literal
// should result 34120000 on BE
实际上,在某些系统中,软件可以设置系统(当前运行在)小端模式还是大端模式。大多数系统只支持特殊情况下的切换,而不是(幸运的是对于系统程序员等)任意来回切换。但可以想象,支持可执行文件定义该特定可执行文件是在 LE 还是 BE 模式下运行。在这种情况下,您不能依赖于选择操作系统和处理器型号......
另一方面,如果硬件只支持一种字节顺序(例如不同形式的 x86),那么我认为不需要在运行时进行检查。你知道它是小端字节序,仅此而已。让系统包含代码来检查它的字节序,并携带从大字节序转换为小字节序的转换方法是浪费的(就性能和代码大小而言)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)