首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在发布模式下,代码行为与预期不符

在发布模式下,代码行为与预期不符
EN

Stack Overflow用户
提问于 2015-07-09 13:41:21
回答 2查看 10.4K关注 0票数 132

以下代码在调试模式和发布模式下生成不同的结果(使用Visual Studio 2008):

代码语言:javascript
复制
int _tmain(int argc, _TCHAR* argv[])
{

    for( int i = 0; i < 17; i++ ) 
    { 
        int result = i * 16;

        if( result > 255 )
        {
            result = 255;
        }

        printf("i:%2d, result = %3d\n", i, result) ; 
    } 

    return 0;
}

debug模式的输出,如预期所示:

代码语言:javascript
复制
i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255

释放模式的输出,其中i:15结果不正确:

代码语言:javascript
复制
i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255

在发布模式下,通过在Visual Studio中选择"Optimization -> Not optimize“,输出结果将是正确的。然而,我想知道为什么优化过程会导致错误的输出。

更新:

根据Mohit JainBy的建议,打印方式:

代码语言:javascript
复制
printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;

释放模式输出正确:

代码语言:javascript
复制
i: 0, result =   0, i*16=0
i: 1, result =  16, i*16=16
(...)
i:14, result = 224, i*16=224
i:15, result = 240, i*16=240
i:16, result = 255, i*16=256
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-09 15:09:34

这很有趣,至少从历史的角度来看是这样。我可以用VC2008 (15.00.30729.01) VC2010 (16.00.40219.01)重现这个问题(目标是32位x86或64位x64)。从VC2012 (17.00.61030)开始,我尝试过的任何编译器都不会出现这个问题。

我用来编译的命令:cl /Ox vc15-bug.cpp /FAsc

由于VC2008(和2010)相当旧,而且修复已经存在好几年了,我认为你不能期望微软采取任何行动,除非使用较新的编译器(尽管可能有人会建议一个变通办法)。

问题是,确定值是否应该强制为255的测试是基于循环计数而不是i * 16表达式的实际结果进行的。编译器只是在应该何时开始强制将值强制为255时得到错误的计数。我不知道为什么会这样--这只是我看到的效果:

代码语言:javascript
复制
; 6    :    for( int i = 0; i < 17; i++ ) 

  00001 33 f6        xor     esi, esi
$LL4@main:
  00003 8b c6        mov     eax, esi
  00005 c1 e0 04     shl     eax, 4

; 7    :    { 
; 8    :        int result = i * 16;
; 9    : 
; 10   :        if( result > 255 )

  // the value `esi` is compared with in the following line should be 15!
  00008 83 fe 0e     cmp     esi, 14            ; 0000000eH
  0000b 7e 05        jle     SHORT $LN1@main

; 11   :        {
; 12   :            result = 255;

  0000d b8 ff 00 00 00   mov     eax, 255       ; 000000ffH
$LN1@main:

; 13   :        }

更新:我在VC2008之前安装的所有版本的VC都有相同的错误,除了VC6 -编译程序会导致VC6编译器崩溃:

代码语言:javascript
复制
vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR

所以这是一个在MSVC中以这样或那样的形式持续了10多年的bug!

票数 116
EN

Stack Overflow用户

发布于 2015-07-09 13:48:55

假设您报告的事实是正确的,这将是一个编译器错误。检查编译器的最新版本。如果错误仍然存在,请提交错误报告。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31309034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档