签名右移:哪个编译器使用逻辑移位

pic*_*c11 11 c c++

我使用Visual Studio,Ubuntu的GCC,英特尔编译器,MinGW测试了右移.所有移位的符号位.我猜Xcode的GCC也是如此.

我知道这种行为是特定于实现的,但看起来所有主要的桌面/服务器编译器都实现了算术移位.是否有任何广泛使用的编译器不会在符号位中移位?

谢谢.

Die*_*Epp 15

C运行在许多不同的体系结构上.我的意思是很多不同的架构.您可以在嵌入式DSP和Cray超级计算机上运行C代码.

人们认为理所当然的C标准中的大多数"实现定义"部分实际上只会破坏模糊的体系结构.例如,DSP和Cray超级计算机CHAR_BIT就像32或64那样巨大.所以如果你在x86上试用你的代码,也许你是慷慨的PowerPC,ARM或SPARC,你就不太可能遇到任何非常奇怪的情况.那没关系.如今大多数代码总是在面向字节的架构上运行,具有二进制补码整数和算术移位.毫无疑问,在可预见的未来,任何新的CPU架构都是一样的.

但是让我们看一下整数的两个最常见的表示形式:二元补码和一元补码:

switch ((-1) >> 1) {
case 0:
case -0:
    puts("Hello, one's complement world!");
    // Possibly sign-magnitude.
    break;
case -1:
    puts("Hello, two's complement world!");
    break;
default:
    puts("Hello, computer without arithmetic shift");
    break;
}
Run Code Online (Sandbox Code Playgroud)

不要出汗./当你想分开时,坚持到>>你需要转移的时候.即使糟糕的编译器也擅长优化这些操作.(并且要记住,x/2 != x>>1如果x是否定的,除非你使用的是补充机器,这几乎肯定不是真的.)

标准确实保证如果(int) x不是负数,那么(int) x >> n == (unsigned) x >> n,编译器没有很大的空间来做一些完全出乎意料的事情.

  • 如果需要,DeathStation 9000 编译器可以在 x86 上自由使用 `shr` 而不是 `sar`。C 标准只是说它是“实现定义的”,而不是 2 的补码系统必须使用算术移位。(与您关于健全的 CPU 的观点类似,许多 C 假设健全/有用的实现选择。仅符合标准并不足以让 C 编译器可用于现实生活中的大部分内容。有时编写完美的可移植代码是不值得的它会导致麻烦或膨胀,因为 ISO C 在某些方面太便携了。) (3认同)
  • @ pic11:改变你的编译器不会做任何事情,这正是我正在做的事情.您需要更改为一个补码架构才能看到差异. (2认同)