Apakah ada perbedaan antara throw()
dan noexcept
selain diperiksa pada waktu proses dan waktu kompilasi?
Artikel Wikipedia C ++ 11 ini menyarankan bahwa penentu lemparan C ++ 03 sudah tidak digunakan lagi.
Mengapa demikian, apakah noexcept
cukup mampu untuk mencakup semua itu pada waktu kompilasi?
[Catatan: Saya telah memeriksa pertanyaan ini dan artikel ini , tetapi tidak dapat menentukan alasan kuat untuk tidak berlaku lagi.]
noexcept
dapat menimbulkan pemeriksaan runtime. Perbedaan utama di antara mereka adalah bahwa memutusnoexcept
sebabstd::terminate
sementara melanggarthrow
sebabstd::unexpected
. Juga perilaku pelepasan tumpukan yang sedikit berbeda dalam kasus ini.Jawaban:
Penentu pengecualian tidak digunakan lagi karena penentu pengecualian umumnya merupakan ide yang buruk .
noexcept
ditambahkan karena ini adalah satu-satunya penggunaan penentu pengecualian yang cukup berguna: mengetahui kapan suatu fungsi tidak akan mengeluarkan pengecualian. Jadi itu menjadi pilihan biner: fungsi yang akan melempar dan fungsi yang tidak akan melempar.noexcept
ditambahkan daripada hanya menghapus semua penentu lemparan selainthrow()
karenanoexcept
lebih kuat.noexcept
dapat memiliki parameter yang waktu kompilasi diselesaikan menjadi boolean. Jika boolean benar, makanoexcept
tongkatnya. Jika boolean salah, makanoexcept
tidak menempel dan fungsinya mungkin muncul.Jadi, Anda bisa melakukan sesuatu seperti ini:
Apakah
CreateOtherClass
membuang pengecualian? Mungkin, jikaT
konstruktor default bisa. Bagaimana kita membedakannya? Seperti ini:Dengan demikian,
CreateOtherClass()
akan membuang iff dari tipe yang diberikan konstruktor default melempar. Ini memperbaiki salah satu masalah utama dengan penentu pengecualian: ketidakmampuannya untuk menyebarkan tumpukan panggilan.Anda tidak dapat melakukan ini dengan
throw()
.sumber
noexcept
. Saya tidak pernah menggunakanthrow()
penentu, dan saya mencoba untuk menentukan apakahnoexcept
benar-benar memberikan manfaat (selain dokumentasi yang diperiksa kompiler).std::terminate
. yang JAUH BURUK ! kode dapat menyelinap ke dalam rilis yang memiliki fungsi yang ditandainoexcept
dan pada waktu proses (artinya di situs pelanggan) pelanggaran terdeteksi. Yang saya maksud adalah jaminan kompilator untuk menghasilkan kode yang tidak membuang pengecualian di tempat pertama.throws()
maka jika pengecualian dilemparkan, tumpukan harus dibatalkan hingga cakupan fungsi itu (sehingga semua variabel otomatis dalam fungsi dimusnahkan) di mana titikterminate()
dipanggil (melaluiunexpected()
). Jika suatu fungsi ditandainoexcept
maka jika pengecualian dilemparkan maka terminate dipanggil (pelepasan tumpukan adalah implementasi yang ditentukan detail).noexcept
tidak diperiksa pada waktu kompilasi.Ketika sebuah fungsi yang dideklarasikan
noexcept
atauthrow()
mencoba untuk menampilkan sebuah pengecualian, satu-satunya perbedaan adalah bahwa satu panggilanterminate
dan panggilan lainnyaunexpected
dan gaya penanganan pengecualian yang terakhir secara efektif sudah tidak digunakan lagi.sumber
throw()
/noexcept
, pemeriksaan waktu kompilasi memastikan bahwa overrider juga memilikinya.std::unexpected()
dipanggil oleh runtime C ++ saat spesifikasi pengecualian dinamis dilanggar: pengecualian dilempar dari fungsi yang spesifikasi pengecualiannya melarang pengecualian jenis ini.std::unexpected()
juga dapat dipanggil langsung dari program.Dalam kedua kasus,
std::unexpected
panggilan yang saat ini diinstalstd::unexpected_handler
.std::unexpected_handler
Panggilan defaultstd::terminate
.sumber