Rumah >pembangunan bahagian belakang >C++ >Mengapakah memberikan nilai kepada pembolehubah kompleks menyebabkan gelung tak terhingga dalam atur cara C, walaupun ia kelihatan seperti tindakan yang tidak berbahaya?
Enigma Kompilasi C dengan Gelagat Gelung Tidak Dapat Diramalkan
Kod berikut mengemukakan isu kompilasi yang menarik:
<code class="c++">#include <iostream> #include <complex> using namespace std; int main() { complex<int> delta; complex<int> mc[4] = {0}; for(int di = 0; di < 4; di++, delta = mc[di]) { cout << di << endl; } return 0; }</code>
Berlawanan kepada output jangkaan "0, 1, 2, 3" yang ditamatkan, kod tersebut menghasilkan pengulangan yang tidak berkesudahan "0, 1, 2, 3, 4, 5, ...". Setelah disiasat, nampaknya perbandingan di < 4 gagal berfungsi dengan betul, mengakibatkan gelung tak terhingga.
Melumpuhkan delta tugasan yang kelihatan tidak berbahaya = mc[di] membetulkan isu secara ajaib, menghasilkan output yang dimaksudkan. Apakah masalah yang ditimbulkan oleh tindakan mudah ini?
Menyelidiki Tingkah Laku yang Tidak Ditakrifkan
Kunci untuk merungkai misteri ini terletak pada pemahaman tingkah laku yang tidak ditentukan. Delta tugasan = mc[di] mencetuskan akses kepada tatasusunan di luar had pada lelaran akhir gelung. Walaupun ramai pengkompil mungkin menganggap tiada gelagat yang tidak ditentukan berdasarkan strategi pengoptimuman, andaian ini sememangnya cacat.
GCC, dengan pengoptimuman dihidupkan, boleh mengoptimumkan gelung secara agresif dengan mengandaikan ketiadaan gelagat yang tidak ditentukan. Pengoptimuman ini membawa kepada inferens yang salah yang di < 4 sentiasa benar, kerana akses tatasusunan di luar sempadan akan membentuk gelagat yang tidak ditentukan.
Akibatnya, gelung menjadi satu tak terhingga, sebagai syarat di < 4 sentiasa dipenuhi. Untuk mengelakkan pengoptimuman yang salah ini, bendera -fno-agressive-loop-optimizations boleh ditambah pada GCC.
Menyingkap Kerja Dalaman Penyusun
Pemeriksaan yang lebih teliti terhadap kod yang dioptimumkan mendedahkan bahawa di < 4 cek dikeluarkan dan digantikan dengan arahan jmp tanpa syarat. Tingkah laku ini sejajar dengan andaian tiada gelagat yang tidak ditentukan, mengakibatkan gelung tak terhingga.
Bertentangan dengan tingkah laku ini, Clang dengan -fsanitize=udefined akan menangkap kes ini. Walau bagaimanapun, GCC dengan bendera yang sama gagal menimbulkan amaran dalam kejadian khusus ini.
Perils of Undefined Behavior
Undefined behavior, seperti yang ditakrifkan oleh standard C, membolehkan hasil yang tidak dapat diramalkan, termasuk mengabaikan sepenuhnya keadaan. Tingkah laku yang tidak ditentukan harus dielakkan pada semua kos, kerana ia boleh membawa kepada ketidakkonsistenan pengkompil dan kelakuan masa jalan yang tidak dijangka.
Untuk mengelakkan perangkap sedemikian, pengaturcara harus berusaha untuk mendapatkan kod yang jelas yang mematuhi semantik yang dimaksudkan. Penyusun juga harus melaksanakan pertahanan yang sesuai untuk memaklumkan pembangun tentang potensi tingkah laku yang tidak ditentukan.
Atas ialah kandungan terperinci Mengapakah memberikan nilai kepada pembolehubah kompleks menyebabkan gelung tak terhingga dalam atur cara C, walaupun ia kelihatan seperti tindakan yang tidak berbahaya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!