这个程序运行结果与编译方式有关,为什么?

Octogen 2002-03-27 05:49:30
问题1:下面这个小程序在VC6的DEBUG编译模式下两个printf函数的输出结果不一致,为什么?
问题2:在Release编译模式下却又结果一致,为什么?

// 编译环境:VC6.0 Enterprise Edition (English) with SP4.

#include <stdio.h>

void main(void)
{
int A = 1;
int B = 32;
printf("1 << ( 1 * 32 ) = %d\n", ( 1 << ( 1 * 32 ) ) );
printf("1 << ( A * B ) = %d\n", ( 1 << ( A * B ) ) );
}

小弟在转换32位色彩时因为类似的问题找了一下午的bug,我苦!
...全文
41 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Octogen 2002-03-28
  • 打赏
  • 举报
回复
多谢acptvc!!!
acptvc 2002-03-28
  • 打赏
  • 举报
回复
感谢您使用微软产品。

根据我的研究,这个问题是由于Intel CPU对SHL指令优化造成的。

首先,由于1 << ( 1 * 32 ) 等于 2^32。由于Integer型变量字长为4。因此,1<<(1*32)得到结果为0。在VC编译时计算出结果,因此,我们的得到的汇编代码是:
var1 = 1 << (1*32) :

mov dword ptr [ebp-offset],0

对于第二个表达式的Shift操作,在Debug版本中,VC将它编译成如下汇编代码:

shl eax, cl

(eax = 1, cl = 32)

根据Intel CPU参考,为了优化操作,Shift操作次数限于5位二进制数(即31次)。因此,CPU的实际操作为0x20&& 0x1F等于0。shift操作实际并未执行。以下是从"Intel Architecture Software Developer's Manual Volume 2: Instruction Set Reference" 中摘录的:

=========

Intel Architecture Compatibility
The 8086 does not mask the shift count. However, all other Intel Architecture processors (starting with the Intel 286 processor) do mask the shift count to five bits, resulting in a maximum count of 31. This masking is done in all operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions.

=========

在Release版本下,由于VC的编译优化1<<A*B (A=1, B= 32) 已计算为0。因此,这个问题不表现出来。

要解决这个问题,我们需要将左移次数限制于31次以下。您需要对代码进行一定的修改来判断和避免这种情况。

-微软全球技术中心 VC开发支持

本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。具体事项可参见使用条款(http://support.microsoft.com/directory/worldwide/zh-cn/community/terms_chs.asp)。

为了为您创建更好的讨论环境,请参加我们的用户满意度调查(http://support.microsoft.com/directory/worldwide/zh-cn/community/survey.asp?key=(S,49854782))。
rovoboy 2002-03-27
  • 打赏
  • 举报
回复
有此等事?怕死了!
Fnoopy 2002-03-27
  • 打赏
  • 举报
回复
很久以前我也遇到过,只能简单的归结为是优化的问题了。具体分析汇编代码我是没本事。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧