릴리스 모드에서 코드 동작이 예상과 다르다.
다음 코드는 디버깅모드 및 릴리스 모드(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의 "Optimization -> Not to optimization"을 선택하면 출력 결과가 정확해집니다.그러나 최적화 프로세스가 잘못된 출력으로 이어질 수 있는 이유를 알고 싶습니다.
업데이트:
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
'itsource' 카테고리의 다른 글
JSON 문자열을 리스트가 아닌 딕셔너리로 변환 (0) | 2022.09.11 |
---|---|
MySQL 여러 값 선택 (0) | 2022.09.06 |
mysqldump를 사용하여 특정 데이터베이스 테이블을 건너뛰는 방법 (0) | 2022.09.06 |
날짜 값이 있는 단일 키를 기준으로 개체 배열 정렬 (0) | 2022.09.06 |
어떻게 외래 키 관계 있는 행동을 바꾸려고 할까?(행동) (0) | 2022.09.06 |