`
javababy1
  • 浏览: 1166573 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

 C/C++移位运算符出界后的结果是不可预期的

 
阅读更多

关于逻辑移位、算术移位可参见 迅雷深大笔试题部分。的一道题。

以前看到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 <stdio.h>

void main()

{

unsigned int i,j;

i=35;

//为什么下面两个左移操作结果不一样?

j=1<<i; // j为8

j=1<<35; // j为0

}

不知是哪里没有理解对。

原因是这样的:i=35;j=1<<i;这两句在VC没有做优化的情况下,将被编译成下面的机器指令:

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.

源文档 <http://blog.csdn.net/zdl1016/archive/2009/09/17/4563910.aspx>

分享到:
评论

相关推荐

    C++ 上课/复习ppt运算符重载.pptx

    C++ 上课/复习ppt运算符重载.pptx

    C语言/C++集成开发环境 Dev-C++

    C语言/C++集成开发环境 Dev-C++。一款优秀的C/C++集成开发软件。

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++ 需要的同学可以下载使用

    C语言/C++ 烟花表白代码

    C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码

    C语言/C++基础之爱心源码

    C语言/C++基础之爱心源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    深入理解C++移位运算符

    下面小编就为大家带来一篇深入理解C++移位运算符。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    c/c++中文帮助文档(API)

    c/c++中文帮助文档(API),包含c和c++所有的库函数

    编译原理课程设计 词法分析 C语言/c++版

    编译原理课程设计之一用编程语言实现词法分析,用C++实现 注释清楚详细,程序风格良好 /*目前实现的功能有: */ /* 0.课程要求的词法分析基本功能 */ ...目前仅支持简单C语言程序,可自行扩充字典内容,以扩大程序功能 */

    二维码(QRcode)生成算法 C语言/C++源码

    #二维码(QRcode)生成算法 C语言/C++ 源码 1. 根据输入字符串识别编码模式; 2. 根据输入字符串长度选择合适的QRcode版本; 3. 将编码转换为二进制位流表示为数据码字; 4. 使用多项式生成纠错码; 5. 将数据码和...

    c语言/c++/qt图形界面

    c语言/c++/qt图形界面

    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语言/C++基础之跨年烟花代码

    C语言/C++基础之跨年烟花代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    2021年最新 C/C++中文参考手册

    2021年最新 C/C++中文参考手册

    c/c++ API chm c/c++函数库

    c/c++ API 主要是c/c++函数 c/c++ API 主要是c/c++函数 c/c++ API 主要是c/c++函数 c/c++ API 主要是c/c++函数 c/c++ API 主要是c/c++函数 c/c++ API 主要是c/c++函数 C++ API chm C++ API chm C++ API chm C++ API...

    C/C++详细函数大全

    该资源包括了C/C++所有函数详细得介绍和说明,并且带有代码示例,资源来源于培训学校chm

    C /C++库函数及文件大全 经典 chm

    Character Standard C Math Standard C Time & Date Standard C Memory Other standard C functions All C Functions C++ C++ I/O C++ Strings C++ String Streams ...

    基于C语言/C++版本的元旦倒计时代码

    基于C语言/C++版本的元旦倒计时代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    lint C/C++质量检查工具

    最初,lint这个工具用来扫描C源文件并对源程序中不可移植的代码提出警告。但是现在大多数lint实用程序已经变得更加严密,它不但可以检查出可移植性问题,而且可以检查出那些虽然可移植并且完全合乎语法但却很可能是...

Global site tag (gtag.js) - Google Analytics