在运行时检测端序的好处是什么?
what is the benefit of detecting endian at runtime?
我已经搜索了宏来确定机器上的端序,没有找到任何标准的proprocessor宏,但是在运行时做了很多解决方案。为什么我要在运行时检测端序?
如果我这样做:
#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;
}
编译器只生成一个函数。
但是如果我这样做(参见predef.endian):
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 wiki:bi-endian这样的双端机器上),那么整个代码都是为小端机器编译的。因此,所有其他的声明,例如int,也都是le。
// compiled on little endian
uint32_t 0x1234; // 0x1234 constant literal
// should result 34120000 on BE
实际上在某些系统中,SOFTWARE可以设置系统(当前运行)是小端模式还是大端模式。大多数系统只支持在特殊情况下的切换,而不是随意地来回切换(对系统程序员来说是幸运的)。但是支持可执行文件定义特定的可执行文件是以LE还是be模式运行是可以想象的。在这种情况下,你不能依赖于挑选操作系统和处理器模型…
另一方面,如果硬件只支持一个端序(例如不同形式的x86),那么我认为没有必要在运行时检查。你知道这是小端序,就是这样。让系统包含检查它是哪个端序的代码,并携带从大端序转换到小端序的转换方法是浪费的(在性能和代码大小方面)。
编译时不一定能进行健壮的端位检测。在某些平台上,即使在运行相同的二进制文件之间,端序也可以改变。
http://gcc.gnu.org/ml/gcc-help/2007-07/msg00343.html我认为在运行时检测端序的唯一好处是您不必乱用宏。正如你自己所注意到的,没有标准的宏说明你正在编译代码的机器的端序是什么,所以你必须自己定义一些东西并将其传递给编译器,或者根据指示体系结构/操作系统的其他标志有条件地定义它,例如:
#ifdef _this_system_
#define LITTLE_ENDIAN
#endif
#ifdef _that_system_
#define BIG_ENDIAN
#endif
但是对于每个可能的体系结构重复很多次,这是混乱和容易出错的。在运行时检查它更容易也更安全。我知道,这看起来很傻,但它确实更实用。
- 在声明中合并两个常量"std::set"(不是在运行时)
- 你能解释一下什么运行时错误是如何解决它的吗?
- 这个递归函数有什么作用?运行时的复杂性是多少?
- 我的代码中出现运行时错误的可能原因是什么?
- 当我运行此C 程序时,该功能是什么
- 一般来说,使用Qt Creator,是什么导致程序在调试模式下编译时正确运行,但在发布模式下崩溃
- 什么是通用运行时组件 #ifdef 适用于Windows(UWP)而不是iOS
- GSL 的预期 (cond) 对运行时施加的性能影响是什么?
- 是什么导致了数组越界运行时错误?
- 导致此运行时错误的原因是什么,如何纠正它?
- 在任何平台上执行任何Qt5应用程序的重要dll文件是什么(运行时文件dll)
- 字符串::substr() 在 C++ 中的运行时是什么
- 是什么阻止g++消除运行时未使用的临时std::数组
- 我在运行时遇到以下错误.它是什么意思?我该如何调试它
- 以下代码中出现运行时错误的原因是什么
- 是否可以使用C++对象组合,其中对象的选择是在运行时确定的
- 类型id(T) 是在运行时还是在编译时被计算
- C++03.在编译时测试右值与左值,而不仅仅是在运行时
- 是直到运行时才创建的方法的虚拟方法
- 注册和使用ActiveX/COM组件,该组件是使用运行时生成的UUID通过IDL创建的