Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Adakah Tingkah Laku Tidak Ditakrifkan Bersembunyi dalam std::string Chaining dalam Kod Bjarne Stroustrup?

Adakah Tingkah Laku Tidak Ditakrifkan Bersembunyi dalam std::string Chaining dalam Kod Bjarne Stroustrup?

Susan Sarandon
Susan Sarandonasal
2024-10-23 18:14:58511semak imbas

Does Undefined Behavior Lurk in std::string Chaining in Bjarne Stroustrup's Code?

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:

  • Ungkapan postfix dijujukan sebelum setiap ungkapan dalam senarai ungkapan.
  • Permulaan setiap parameter dijujukan secara tidak tentu berkenaan dengan mana-mana parameter lain.

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn