Kode berikut menghasilkan hasil yang berbeda di bawah mode debug dan mode rilis (menggunakan 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;
}
Output dari mode debug, yang seperti yang diharapkan:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 240
i:16, result = 255
Output mode rilis, di mana hasil i: 15 tidak benar:
i: 0, result = 0
i: 1, result = 16
(...)
i:14, result = 224
i:15, result = 255
i:16, result = 255
Dengan memilih "Optimasi -> Tidak untuk mengoptimalkan" di Visual Studio dalam mode rilis, hasil output akan benar. Namun saya ingin tahu mengapa proses optimasi dapat menyebabkan output yang salah.
Memperbarui:
Seperti yang disarankan oleh Mohit JainBy, dicetak oleh:
printf("i:%2d, result = %3d, i*16=%d\n", i, result, i*16) ;
Output mode rilis sudah benar:
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
c++
c
optimization
visual-studio-2008
compiler-bug
Lorris Lin
sumber
sumber
i * 16
dalam pos, dan hasilnya benar.Jawaban:
Ini menarik, setidaknya dari perspektif sejarah. Saya dapat mereproduksi masalah dengan VC 2008 (15.00.30729.01) dan VC 2010 (16.00.40219.01) (menargetkan 32-bit x86 atau 64-bit x64). Masalahnya tidak terjadi dengan salah satu kompiler yang saya coba mulai dengan VC 2012 (17.00.61030).
Perintah yang saya gunakan untuk mengkompilasi:
cl /Ox vc15-bug.cpp /FAsc
Karena VC 2008 (dan 2010) agak lama dan perbaikannya telah berlangsung selama beberapa tahun sekarang, saya tidak berpikir Anda dapat mengharapkan tindakan apa pun dari Microsoft kecuali untuk menggunakan kompiler yang lebih baru (meskipun mungkin seseorang dapat menyarankan solusi).
Masalahnya adalah tes untuk menentukan apakah nilai harus dipaksa
255
dilakukan berdasarkan jumlah loop daripada hasil aktual darii * 16
ekspresi. Dan kompiler hanya mendapatkan hitungan yang salah ketika harus mulai memaksa nilai255
. Saya tidak tahu mengapa itu terjadi - itu hanya efek yang saya lihat:Pembaruan : Semua versi VC yang saya instal lebih awal dari VC 2008 memiliki bug yang sama, kecuali VC6 - mengkompilasi program membuat crash kompilator VC6:
Jadi ini adalah bug yang bertahan di MSVC dalam satu atau lain bentuk selama lebih dari 10 tahun!
sumber
result > 255
keresult >= 255
berperilaku dengan benar. Dalam VS2010 yang berubahcmp esi, 14
menjadicmp esi, 16
(danjle
kejl
).Anggap fakta yang Anda laporkan benar, ini akan menjadi bug penyusun. Periksa versi kompiler terbaru. Jika bug masih ada, kirim laporan bug.
sumber