C/C++移位运算符出界后的结果是不可预期的
来源:互联网 发布:怪物猎人p3数据库安卓 编辑:程序博客网 时间:2024/04/29 21:47
以前看到C++标准上说,移位运算符(<<、>>)出界时的行为并不确定:
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
我当时也没有深究过这个问题。前几天有个网友来信问起这件事,我才发现,这和Intel CPU的移位运算有关。下面是那位网友的来信以及我的回复:
您好!运算符<<作为位操作中的高效的操作,但我遇到一个问题:下面在VC环境下发现一个很不明白的地方,下面标注。
#include
void main()
{
unsigned int i,j;
i=35;
//为什么下面两个左移操作结果不一样?
j=1< j=1<<35; // j为0
}
不知是哪里没有理解对。
原因是这样的:i=35;j=1<
mov dword ptr [i],23h
mov eax,1
mov ecx,dword ptr [i]
shl eax,cl
mov dword ptr [j],eax
在shl一句中,eax=1,cl=35。而Intel CPU执行shl指令时,会先将cl与31进行and操作,以限制左移的次数小于等于31。因为35 & 31 = 3,所以这样的指令相当于将1左移3位,结果是8。
而j=1<<35;一句是常数运算,VC即使不做优化,编译器也会直接计算1<<35的结果。VC编译器发现35大于31时,就会直接将结果设置为0。这行代码编译产生的机器指令是:
mov dword ptr [j],0
对上面这两种情况,如果把VC编译器的优化开关打开(比如编译成Release版本),编译器都会直接将结果设置为0。
所以,在C/C++语言中,移位操作不要超过界限,否则,结果是不可预期的。
下面是Intel文档中关于shl指令限制移位次数的说明:
The destination operand can be a register or a memory location. The count operand can be an immediate value or register CL. The count is masked to 5 bits, which limits the count range to 0 to 31. A special opcode encoding is provided for a count of 1.
- C/C++移位运算符出界后的结果是不可预期的
- C/C++移位运算符出界后的结果是不可预期的
- C/C++移位运算符出界后的结果是不可预期的
- C/C++移位运算符出界后的结果是不可预期的
- C/C++移位运算符出界后的结果是不可预期的
- C/C++移位运算符出界后的计算规则,需要懂汇编啊!
- C语言的移位运算符
- C语言的移位运算
- C语言负数的移位运算
- C语言中数值的移位运算
- C语言负数的移位运算
- c中的移位运算符
- C语音移位运算符
- C语言移位运算符
- C语言移位运算符
- C语言移位运算符
- C语言移位运算符
- C/C++移位运算符
- yc++最新版出来了
- 学习xerces-c使用中
- 中国人自己的c/c++编译器、网页浏览器内核
- 网络寒冬下的团队管理
- 关于C++模板和重载的小问题
- C/C++移位运算符出界后的结果是不可预期的
- C++编译器检索VTABLE的具体方法不同
- 在Win2K/XP/2K3中 模拟实现VISITA效果对话框
- C程序员面试
- 右键文件关联
- 在console中 使用C Runtime 和 STL 显示 Unicode中文
- [MSSQL]将用户表 存储过程 变成系统的
- [C++] 获取字体点阵
- [WDM]驱动程序框架 我还没写完 好忙 没时间玩