Adakah Rangkaian Kaedah STL mengekalkan Perintah Penilaian dalam C?

Patricia Arquette
Lepaskan: 2024-10-24 03:28:01
asal
500 orang telah melayarinya

Does STL Method Chaining Preserve Evaluation Order in C  ?

Adakah Merangkai Kaedah STL dalam C Mengekalkan Perintah Penilaian?

Dalam Bjarne Stroustrup "The C Programming Language" edisi ke-4, coretan kod berikut contoh rantaian kaedah:

<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>
Salin selepas log masuk

Kod ini menilai pernyataan dari kiri ke kanan, mengubah rentetan s secara berperingkat. Walau bagaimanapun, tingkah laku ungkapan ini adalah samar-samar bergantung pada pengkompil yang digunakan:

  • Dentang: Penilaian mengikut susunan yang dijangkakan, menghasilkan s sebagai "Saya telah mendengar ia berfungsi hanya jika anda percaya kepadanya".
  • GCC: Urutan penilaian tidak dapat diramalkan, menyebabkan s mengambil nilai yang salah.
  • Visual Studio: Sama seperti GCC, penilaian adalah samar-samar, selalunya menghasilkan hasil yang tidak betul yang sama.

Menyingkap Tingkah Laku Yang Tidak Ditentukan

Kod menunjukkan tingkah laku yang tidak ditentukan kerana tidak tentu susunan penilaian subungkapan, walaupun tidak menggunakan tingkah laku yang tidak ditentukan. Inti isu terletak pada susunan penilaian argumen fungsi dalam panggilan fungsi berantai.

Khususnya, untuk sub-ungkapan berikut:

  • s.find("even")
  • s.find(" don't")

Perintah penilaian mereka tidak pasti berkenaan dengan:

  • s.replace(0, 4 , "")

Ini bermakna panggilan carian boleh dinilai sebelum atau selepas panggilan ganti, menjejaskan panjang s dan seterusnya mengubah keputusan panggilan carian.

Ilustrasi dengan Fungsi Carian Tersuai

Untuk menunjukkan kekaburan ini, versi kod yang diubah suai menggunakan fungsi my_find tersuai yang melaporkan kedudukan rentetan carian dalam setiap penilaian sub-ungkapan:

<code class="cpp">std::string::size_type my_find(std::string s, const char *cs) {
  std::string::size_type pos = s.find(cs);
  std::cout << "position " << cs << " found: " << pos << std::endl;
  return pos;
}</code>
Salin selepas log masuk

Menjalankan kod ini dengan pengkompil yang berbeza menghasilkan hasil yang berbeza bergantung pada susunan penilaian:

  • Clang: my_find dinilai untuk "genap" sebelum ia dinilai untuk "jangan", menghasilkan output yang betul.
  • GCC: my_find dinilai untuk "jangan" sebelum dinilai untuk "genap", yang membawa kepada hasil yang salah .

C 17 Changes

Standard C 17 (p0145r3) memperkenalkan pemurnian kepada peraturan perintah penilaian ungkapan untuk menangani kekaburan ini. Ia mengukuhkan susunan penilaian untuk ungkapan postfix dan senarai ungkapannya seperti berikut:

  • Ungkapan postfix disusun sebelum setiap ungkapan dalam senarai ungkapan dan sebarang hujah lalai.

Ini memastikan bahawa panggilan kaedah berantai menilai dalam susunan yang dijangka, menyelesaikan tingkah laku yang tidak ditentukan ini dalam C 17.

Atas ialah kandungan terperinci Adakah Rangkaian Kaedah STL mengekalkan Perintah Penilaian dalam C?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!