关于C/C++中算术左移的小发现

今天在学习系统级程序设计的时候,无意间发现一个神奇的现象:

在这里插入图片描述
可能大家第一时间看不太懂,我稍微解释一下:这里x=5(不重要),n=0,以此计算tempN=32(这一点没有问题),但随后测试中发现,立即数1在进行逻辑(算术)左移的时候,应该是会在右边补0,那么这样分析结果最后应该是0,但发现最后结果竟然不是!!!!结果竟然还是1!!!!
???什么鬼???于是不甘心的我又试了试(1<<32)的结果,发现最终结果确实是0.这一下就给我搞懵逼了。。。。。。为啥一个是立即数,另一个是值一样的标识符,但最后的结果却不一样。冷静分析了一直,还是应该看看汇编源程序:

这区别还是有点大啊
看了反汇编的代码后,我发现,对于(1<<32)的运算,C++编译器竟然直接给我一句代码按死了。。。直接给a赋值了0;而对于tempN寄存器中的内容,他采用的是算术左移的指令。Emmmmm….好像也没啥毛病,shl指令也是每次左移然后低位填充0啊。。。还是看看别人怎么说吧。诶!有为朋友跟我有一样的问题,点击查看原文:
他发现的情况是:当位移32位时,会得到原来一模一样的值,我自己试了试,woc!还真是!此外,还有朋友说当超过32位时,编译器会自动进行取模运算,并且会利用余数进行左移操作(不过好像也是自己得出的结论,虽然理论证明好像是对的)。
再看看C++文档,里面说的是:
在这里插入图片描述
翻译一下就是:如果加法表达式为负,或者加法表达式大于或等于(提升的)移位表达式中的位数,则移位操作的结果是未定义的。如果加法表达式为0,则不执行移位操作。

那…要是左移32位算什么?难道是(32%32 ==0)所以按0处理,不执行位移操作?这是我自己的猜想吧,希望有大神可以研究出来。(不过网上似乎都找不太到相应的报错情况,说明这些无聊的问题大佬们都不屑一顾吧。。。)

害,还是乖乖的按照人家设定好的来写,别老在规则边缘试探啦!

最后作死一下,改个64试一试:

在这里插入图片描述.
似乎把编译器搞得怀疑人生了。(哈哈哈哈,直接bp+1执行下一条去了)

重要补充:

根据《深入理解计算机系统》的作者Randal E. Bryant所说,当一个单字节的变量x进行左移8位运算时,你以为你会得到0的结果,但事实上绝大多数的编译器会将这个数mod 8 ,所以最后得到的结果确实是x本身。
当然很多机器会给出警报,但并不是所有的机器都会这样做,所以这也是C的“乐趣”,即并不能保证只有一种方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值