编译器如何知道字节序将是什么?

RPF*_*ltz 2 c++ optimization bit-shift endianness

我想在运行时使用测试来确定字节序,以便我可以确定移位的行为,并注意到我的编译器有点奇怪的优化.这表明它将运行的机器的字节序在编译时是已知的.

这是我定时的两个例程.使用const的例程2大约快了33%.

/* routine 1 */
int big_endian = 1 << 1;
for (register int i = 0; i < 1000000000; ++i) {
  int value = big_endian ? 5 << 2 : 5 >> 2;
  value = ~value;
}
/* routine 2 */
const int big_endian = 1 << 1;
for (register int i = 0; i < 1000000000; ++i) {
  int value = big_endian ? 5 << 2 : 5 >> 2;
  value = ~value;
}
Run Code Online (Sandbox Code Playgroud)

例程2的速度与使用在编译时可计算的常量表达式的速度相匹配.如果换班的行为取决于处理器,这怎么可能?

此外,在一个侧面说明,为什么我们调用与最终数目至少显著位尾数号码,以及那些以结束显著位尾数号码.

编辑:

评论中的一些人声称按位移位与字节序无关.如果这是真的,这是否意味着一个数字,如3总是存储00000011 (big endian)和从来没有像11000000 (little endian)?如果这是真实的情况,这实际上似乎是有道理的,使用小端时,是不是很怪异的行为,因为10000000 00000000 00000000 (128) 转移一个人的左边会00000000 00000001 00000000 (256)?提前感谢你.

yad*_*taf 6

编译器始终将构建的目标知道为指令,并且字节序特定于架构.

大多数情况下,目标是当前机器之一或更通用的机器,除非您进行交叉编译.


Kei*_*all 6

编译器假定目标处理器具有字节序.大多数情况下这是显而易见的,例如x86总是小端的.对于可能是其中任何一种的体系结构,如果默认设置不适合您,通常会有编译器开关.例如,gcc/arm有-mlittle-endian(默认)和-mbig-endianflags.