C ++中右移的未定义行为 [英] Undefined behavior of right-shift in C++

查看:121
本文介绍了C ++中右移的未定义行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自cppreference.com:

From cppreference.com:

对于无符号a和具有非负值的带符号a,其值 a >> b是a/2 b 的整数部分.对于负a,a的值>> b是实现定义的(在大多数实现中, 算术右移,以便结果保持负数.)

For unsigned a and for signed a with nonnegative values, the value of a >> b is the integer part of a/2b . For negative a, the value of a >> b is implementation-defined (in most implementations, this performs arithmetic right shift, so that the result remains negative).

在任何情况下,如果右操作数的值为负或为 大于或等于提升后的左操作数中的位数, 行为是不确定的.

In any case, if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined.

如果右操作数大于或等于提升后的左操作数的位数,为什么会有不确定的行为?
在我看来,结果应该为0(至少对于无符号/正整数)...

Why do we have an undefined behavior in case the right operand is greater or equal to the number of bits in the promoted left operand?
It seems to me that the result should be 0 (at least for unsigned/positive integers)...

尤其是对于g ++(版本4.8.4,Ubuntu):

In particular, with g++ (version 4.8.4, Ubuntu):

unsigned int x = 1;
cout << (x >> 16 >> 16) << " " << (x >> 32) << endl;

给出:0 1

推荐答案

C ++的目标之一是允许快速,高效的代码接近硬件".在大多数硬件上,可以通过单个操作码实现整数右移或左移.麻烦的是,在这种情况下,不同的CPU在位移幅度大于位数的情况下会有不同的行为.

One of the goals of C++ is to allow for fast, efficient code, "close to the hardware". And on most hardware, an integer right shift or left shift can be implemented by a single opcode. The trouble is, different CPUs have different behavior in this case where the shift magnitude is more than the number of bits.

因此,如果C ++强制执行移位操作的特定行为,则在为操作码行为不符合所有标准要求的CPU生成代码时,编译器将需要插入检查和逻辑以确保结果符合在所有情况下均为标准配置.除非优化程序可以证明根本不会发生这种情况,否则几乎所有使用内置移位运算符的情况都将发生这种情况.添加的检查和逻辑可能会降低程序的速度.

So if C++ mandated a particular behavior for shift operations, when producing code for a CPU whose opcode behavior doesn't match all the Standard requirements, compilers would need to insert checks and logic to make sure the result is as defined by the Standard in all cases. This would need to happen to almost all uses of the built-in shift operators, unless an optimizer can prove the corner case won't actually happen. The added checks and logic would potentially slow down the program.

这篇关于C ++中右移的未定义行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆