Rumah >pembangunan bahagian belakang >C++ >Adakah Tingkah Laku Tidak Ditakrifkan Bersembunyi dalam std::string Chaining dalam Kod Bjarne Stroustrup?
Adakah Ungkapan Rantaian std::string dalam Kod Bjarne Stroustrup Menunjukkan Tingkah Laku Tidak Ditakrifkan?
Dalam "Bahasa Pengaturcaraan Edisi C" Bjarne Stroustrup , coretan kod mencontohkan perangkaian menggunakan kaedah ganti std::string:
<code class="cpp">void f2() { std::string s = "but I have heard it works even if you don't believe in it"; s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, ""); assert(s == "I have heard it works only if you believe in it"); }</code>
Kod ini, walau bagaimanapun, mempamerkan gelagat yang tidak ditentukan dan bukannya menggunakan gelagat yang tidak ditentukan.
The sebab bagi tingkah laku yang tidak ditentukan ini terletak pada susunan penilaian, yang tidak ditentukan untuk sub-ungkapan bagi panggilan fungsi berantai. Dalam kes ini, panggilan fungsi s.find dinilai sama ada sebelum atau selepas panggilan s.replace yang pertama, mengubah panjang rentetan yang terhasil dan menjejaskan keputusan panggilan carian berikutnya.
Contoh dalam soalan menunjukkan perkara ini: apabila dinilai oleh penyusun yang berbeza (clang, gcc), hasil yang berbeza diperoleh disebabkan oleh susunan penilaian yang berbeza-beza.
Butiran
Argumen fungsi mempunyai susunan penilaian yang tidak ditentukan dan sementara panggilan fungsi rantaian memperkenalkan susunan penilaian kiri ke kanan untuk setiap panggilan fungsi, hujah setiap panggilan disusun sebelum hanya berkenaan dengan panggilan fungsi tertentu itu.
Dalam contoh, ketidakpastian ini timbul dalam penilaian s.find("genap") dan s.find(" jangan") berkenaan dengan s.replace(0, 4, "").
Mengabaikan sub-sub selanjutnya -pecahan ungkapan, turutan langkah penilaian dan saling kebergantungan mereka boleh digambarkan seperti berikut:
Step 1: s.replace(0, 4, "") // A Step 2: s.find("even") // B Step 3: s.replace(B, 4, "only") // C Step 4: s.find("don't") // D Step 5: s.replace(D, 6, "") // E
Sementara A dijujukan sebelum B, yang seterusnya dijujukan sebelum C, terdapat tiada hubungan penjujukan antara B dan D berkenaan dengan A. Akibatnya, D boleh dinilai sama ada sebelum atau selepas A, membawa kepada hasil yang berbeza berdasarkan urutan yang dipilih.
C 17 Perubahan
Standard C 17 mengukuhkan susunan peraturan penilaian untuk postfix-expressions dan senarai ekspresinya, memberikan kod yang dipersoalkan tingkah laku yang dinyatakan dengan baik. Penjujukan adalah seperti berikut:
Oleh itu, dalam C 17 dan kemudian, kod ini akan sentiasa dinilai dengan betul.
Atas ialah kandungan terperinci Adakah Tingkah Laku Tidak Ditakrifkan Bersembunyi dalam std::string Chaining dalam Kod Bjarne Stroustrup?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!