릴리스 모드에서 코드 동작이 예상과 다릅니다
다음 코드는 디버그 모드와 릴리스 모드 (Visual Studio 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
릴리스 모드에서 Visual Studio에서 "최적화-> 최적화하지 않음"을 선택하면 출력 결과가 정확합니다. 그러나 최적화 프로세스가 잘못된 결과를 초래할 수있는 이유를 알고 싶습니다.
최신 정보:
Mohit JainBy가 제안한대로 다음과 같이 인쇄합니다.
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)은 다소 오래되었고 수정 사항이 몇 년 동안 있었으므로 새로운 컴파일러를 사용하는 것을 제외하고 Microsoft의 조치를 기대할 수 있다고 생각하지 않습니다 (누군가 대안을 제안 할 수도 있음).
문제는 값을 강제로 결정해야하는 테스트가 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 : }
업데이트 : VC 2008 이전에 설치 한 모든 버전의 VC에는 VC6을 제외하고 동일한 버그가 있습니다. 프로그램을 컴파일하면 VC6 컴파일러가 충돌합니다.
vc15-bug.cpp(10) : fatal error C1001: INTERNAL COMPILER ERROR
따라서 이것은 MSVC에서 10 년 이상 한 형태로 지속 된 버그입니다!
보고 된 사실이 정확하다고 가정하면 컴파일러 버그 일 수 있습니다. 최신 버전의 컴파일러를 확인하십시오. 버그가 여전히 존재하면 버그 보고서를 제출하십시오.
참고URL : https://stackoverflow.com/questions/31309034/in-release-mode-code-behavior-is-not-as-expected
'Programing' 카테고리의 다른 글
홀수 업데이트와 Java 업데이트의 차이점은 무엇입니까? (0) | 2020.06.30 |
---|---|
Swift의 프로토콜과 Java의 인터페이스 비교 (0) | 2020.06.30 |
콜 레이션이란 무엇입니까? (0) | 2020.06.30 |
Docker 컨테이너에서 여러 프로그램을 실행할 수 있습니까? (0) | 2020.06.30 |
스레드 대 스레드 풀 (0) | 2020.06.30 |