在发布模式下,代码行为并不像预期的那样。

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

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

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;
}

调试模式的输出,如预期的那样:

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255

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

i: 0, result =   0
i: 1, result =  16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255

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

最新情况:

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

发布模式输出是正确的:

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
提问于
用户回答回答于

我可以用VC 2008(15.00.30729.01)再现这个问题,VC 2010(16.00.40219.01)(针对32位x86或64位x64),这个问题不会出现在我尝试过的从VC 2012(17.00.61030)开始的编译器中。

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

因为VC 2008(和2010)已经相当老了,而且修复已经有好几年了,我认为除了使用更新的编译器之外,不可能期望微软采取任何行动。

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

; 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   :        }

除了VC6编译程序崩溃VC6编译器之外,比VC 2008更早安装的所有版本的VC I都有相同的错误:

vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR
用户回答回答于

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

扫码关注云+社区