相关疑难解决方法(0)

当左侧操作数具有负值时,为什么左移操作会调用未定义的行为?

在C中,当左侧操作数具有负值时,左移位操作会调用未定义的行为.

ISO C99相关引用(6.5.7/4)

E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充.如果E1具有无符号类型,则结果的值为E1×2 E2,比结果类型中可表示的最大值减少一个模数.如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定.

但在C++中,行为定义明确.

ISO C++ - 03(5.8/2)

E1 << E2的值是E1(解释为位模式)左移E2位位置; 空位是零填充的.如果E1具有无符号类型,则结果的值为E1乘以上升到功率E2的数量2,如果E1的类型为无符号长,则减少模ULONG_MAX + 1,否则为UINT_MAX + 1.[注意:标题中定义了常量ULONG_MAX和UINT_MAX).]

这意味着

int a = -1, b=2, c;
c= a << b ;
Run Code Online (Sandbox Code Playgroud)

在C中调用未定义的行为,但行为在C++中定义良好.

是什么迫使ISO C++委员会考虑与C中的行为相对应的行为?

另一方面,implementation defined当左操作数为负时,行为是按位右移操作,对吗?

我的问题是为什么左移操作在C中调用未定义的行为,为什么右移操作符只调用实现定义的行为?

PS:请不要给出答案,例如"这是未定义的行为,因为标准是这样说的".:P

c c++ bit-shift undefined-behavior language-lawyer

42
推荐指数
3
解决办法
2万
查看次数

算术右移给出虚假的结果?

我必须在这里绝对疯狂,但gcc 4.7.3在我的机器上给出了最荒谬的结果.这是我正在测试的确切代码:

#include <iostream>

using namespace std;

int main(){
  unsigned int b = 100000;
  cout << (b>>b) << endl;
  b = b >> b;
  cout << b << endl;
  b >>= b;
  cout << b << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,这是正确的本身转移任意数量应该导致0(n/(2^n) == 0整数除法,n>1正/无符号),但不知何故,这里是我的输出:

100000
100000
100000
Run Code Online (Sandbox Code Playgroud)

我疯了吗?可能会发生什么?

c++ gcc bit-shift undefined-behavior

30
推荐指数
2
解决办法
1641
查看次数

标签 统计

bit-shift ×2

c++ ×2

undefined-behavior ×2

c ×1

gcc ×1

language-lawyer ×1