C++ 当您将shift位移到变量末尾之外时会发生什么情况?

C++ 当您将shift位移到变量末尾之外时会发生什么情况?,c++,c,bit-manipulation,C++,C,Bit Manipulation,如果您有一些变量(在堆栈上),并且您的位左移或右移超出了它的末端,会发生什么情况 i、 e 如果x是一个指向一个字节的内存的指针,而您也做了同样的事情,该怎么办 byte* x = obtain pointer from somewhere; *x = 1; *x >> N; 它(不一定)变成零。行为未定义(C99§6.5.7,“位移位运算符”): 如果右操作数的值为 负或大于或等于 到提升的左侧的宽度 操作数,行为未定义 (C++0x§5.8,“移位运算符”): 如果正确,则该行

如果您有一些变量(在堆栈上),并且您的位左移或右移超出了它的末端,会发生什么情况

i、 e

如果x是一个指向一个字节的内存的指针,而您也做了同样的事情,该怎么办

byte* x = obtain pointer from somewhere;
*x = 1;
*x >> N;
它(不一定)变成零。行为未定义(C99§6.5.7,“位移位运算符”):

如果右操作数的值为 负或大于或等于 到提升的左侧的宽度 操作数,行为未定义

(C++0x§5.8,“移位运算符”):

如果正确,则该行为未定义 操作数为负或大于 或等于以位为单位的 提升的左操作数


正在移位的值的存储对这一切都没有影响。

我认为您对位移位的作用感到困惑。它们是算术运算符,相当于乘或除2的幂(模化C如何处理负数的一些奇怪之处)它们不移动内存中的任何位。更改任何变量/内存内容的唯一方法是将表达式的结果赋回某个位置


至于当位移位运算符的右操作数大于或等于左表达式类型的宽度时会发生什么情况,行为是未定义的。

我认为您感到困惑
x>>y
一开始实际上并没有改变x。它计算一个新值


正如Stephen所指出的,
y
不能为负,并且必须小于“提升后的左操作数的宽度”(在类型提升时读取)。但除此之外,移位“结束”的位将被简单地丢弃
1>>2
(请注意,
2
不是负数,它小于用于表示
1
的位数,可能是32,但肯定至少是16)计算为0。

Uh。。。此处的情况不一定是“右操作数为负”或“右操作数大于或等于提升后的左操作数的宽度”。OP没有指定N的值。我将问题理解为“我认为该值在这里不重要,因为
x
是1”。重要说明:本例中的宽度表示
CHAR\u BIT*sizeof(var)
,而不是
log2(var)
!在过去的几年里,我看到了两种行为,N大于或等于单词大小。行为1,到目前为止最常见的,是所有位“移位”,结果为零。另一个行为是N被静默地缩减为字大小的模。例如,对于32位类型的x,这个架构上的x>>32就是一个不可操作的例子。@GregS:其他行为是可能的(并且确实发生在现实世界中)。例如,在ARM上的大多数编译器中,可变移位量被减少到256模,然后饱和到0-32的范围(硬件就是这样做的;少数编译器发出额外的指令以获得不同的行为,但大多数没有)。我也看到了一些其他的行为。反问:如果你期望下一个内存位置的位发生移位,接下来会发生什么?这是否意味着来自下一个内存位置的位将进一步移位?有了这个逻辑,所有的内存都会移位。你不认为它必须停在某个地方吗?那么真正的问题是,在内存空间边缘的第一位和最后一位会发生什么@jalf:如果至少有两个平行的宇宙,这不是问题。
byte* x = obtain pointer from somewhere;
*x = 1;
*x >> N;