Apakah jaminan keselamatan pengecualian yang kuat dengan argumen nilai demi nilai yang dapat menimbulkan kehancuran mungkin?

8

Misalkan Anda memiliki tipe dengan pelempar destruktor, dan fungsi menerimanya berdasarkan nilai.
Bisakah operasi itu memberikan sesuatu yang lebih baik daripada jaminan pengecualian dasar?
Atau dirumuskan secara berbeda, dapatkah seseorang mengabaikan penghancuran argumen yang disahkan oleh nilai ketika menentukan apakah suatu operasi memiliki komit-dan-kembalikan-semantik?

#include <cstdlib>

struct X {
    ~X() noexcept(0) {
        if(rand()%6 == 0) throw 0;
    }
    // some state
};

void update(database db, X arg) noexcept;

X x;
update(db, x);

Secara pribadi, berdasarkan definisi dari wikipedia

  1. Keamanan pengecualian yang kuat , juga dikenal sebagai semantik komit atau kembalikan : Operasi dapat gagal, tetapi operasi yang gagal dijamin tidak memiliki efek samping, sehingga semua data mempertahankan nilai aslinya

Saya tidak berpikir itu berguna untuk menggambarkan updatesebagai sangat pengecualian aman, meskipun fungsi itu sendiri bahkan tidak bisa melempar

Saya akan menghargai seseorang yang menunjukkan kebodohan pemahaman saya saat ini, atau memberikan argumen yang lebih baik.

Deduplicator
sumber
Bagaimana jika metode di kelas melempar dan pemanggil memutuskan untuk membuang objek? Akankah destructor masih menutup transaksi?
Robert Harvey
Metode di kelas mana? Dan tutup transaksi apa? Maaf, tapi saya bingung sekarang.
Deduplicator
Nah, kecuali pola kenang-kenangan digunakan, atau transaksi basis data terlibat, saya tidak melihat bagaimana keadaan kelas tidak hilang saat objek dibuang, kecuali Anda mengatakan itu adalah kelas tanpa kewarganegaraan.
Robert Harvey
2
Pertanyaannya terinspirasi oleh argumen di sini: chat.stackexchange.com/rooms/32049/... chat.stackexchange.com/rooms/32061/…
Deduplicator
4
Secara umum, penghancur lempar adalah racun lengkap untuk semua jaminan keselamatan pengecualian. Hanya saja semakin sulit dengan perintah besarnya.
Sebastian Redl

Jawaban:

7

Saya tidak benar-benar yakin dalam retrospeksi, tetapi apakah updateitu generik atau apakah Xabstrak (mis: dikloning dan dihancurkan) - yaitu, jika updatetidak dapat mengetahui apa pun yang konkret X, maka untuk semua tujuan praktis saya akan menggambarkannya sebagai memiliki yang kuat jaminan pengecualian keamanan. Paling tidak itu dekat dengan jaminan-keamanan yang kuat yang pernah Anda dapatkan dalam konteks abstrak tanpa x-raying tipe data.

Namun, Xkonkret, sehingga membuat pertanyaan ini jauh lebih kabur. Saya masih tergoda untuk mengatakan bahwa update"memiliki jaminan keselamatan pengecualian yang kuat" karena melakukan segala yang dapat dilakukannya untuk menegakkannya. Apakah itu terdengar seperti pembicaraan gila? Itu berlaku untuk saya, tetapi saya tidak bisa mengatakannya lebih baik.

Terutama dalam konteks lingkungan tim di mana satu penulis mengimplementasikan updatedan yang lainnya mengimplementasikan X, tidak ada yang bisa memberikan jaminan keselamatan-pengecualian yang kuat karena Xdapat dimodifikasi dengan cara yang melanggar jaminan dengan cara yang sepenuhnya di luar kendali update. Untuk tujuan praktis, saya pikir jika updatemelakukan apa saja yang dapat dan harus memutar kembali efek sampingnya di jalur yang luar biasa, praktis memberikan jaminan keselamatan pengecualian yang kuat.

Kalau tidak, jaminan keselamatan pengecualian yang kuat menjadi sesuatu yang tidak praktis untuk diberikan dalam banyak skenario. Berbagai hal dapat berubah di luar kendali fungsi. Hal-hal bisa abstrak dengan cara di luar pengetahuan fungsi. Seluruh jaminan hampir tidak mungkin diberikan di mana pun. Dalam hal ini, dapatkah kita mengatakan bahwa jaminan pengecualian yang kuat akan updatemenyebarkan tanggung jawab Xuntuk dipatuhi, atau apakah itu updateyang diperlukan untuk mengetahui bagaimana Xakan diterapkan setiap saat? Saya tidak tahu Bagaimanapun juga ini sangat tidak praktis, dan saya tidak suka ketidakpraktisan.

Jadi saya akan pergi dengan minyak mentah, ya, " updateadalah pengecualian-aman, tetapi Xpergi fubar dan mengacaukan segalanya. update'sSetidaknya itu bukan kesalahan. Jangan menuntut penulis pembaruan! Menuntut penulis X!" . Saya ingin menggambarkan Xsebagai sekadar fubar di sini, dan updatemungkin memberikan jaminan keselamatan pengecualian yang kuat yang dikacaukan oleh fakta bahwa Xfubar. Yaitu, kecuali ada pemahaman tingkat antarmuka yang sangat sulit bahwa X'sdestructor dirancang untuk melempar, dalam hal ini saya tidak tahu bagaimana menggambarkannya kecuali sebagai "masalah besar". Saya pikir kita perlu cetakan yang bagus dan disclaimer untuk mendapatkan jaminan ini.pembaruan memberikan jaminan keamanan-pengecualian yang kuat asalkan [...]. Tidak ada pengembalian uang jika ini bukan masalahnya!

Ini seperti pertanyaan filosofis bagi saya, menarik untuk dipikirkan tetapi mungkin satu tanpa jawaban yang sempurna. Dan apa pula jaminannya? Bisakah kita menjamin sesuatu? Saya mungkin menjamin bahwa minum bir akan membuat saya mabuk dan itu kelihatannya benar setiap saat, tetapi bagaimana jika makhluk luar angkasa mengintervensi dan menggunakan semacam teknologi asing yang membuat saya sadar tidak peduli berapa banyak saya minum? Saya tidak bisa menjaminbahwa ini tidak akan terjadi. Saya hanya dapat mengatakan bahwa ini sangat mustahil dan bahwa jika peristiwa seperti itu terjadi, saya tidak berdaya melawannya. Saya melakukan bagian saya. Saya minum bir saya. Aku seharusnya mabuk. Saya sangat menjaminnya. Tapi itu tidak pasti. Selalu ada beberapa kemungkinan, betapa pun jauh dari itu, bahwa jaminan itu mungkin tidak berlaku. Bagaimana dengan keamanan benang? Nah, bagaimana jika pesawat ruang angkasa alien datang dan zaps perangkat keras kami dan mengatur ulang instruksi dalam memori sehingga fungsi thread-safe yang sudah ada sekarang tidak lagi thread-safe saat runtime? Saya tidak dapat menjamin bahwa ini tidak akan terjadi. Tetapi saya akan menjamin keselamatan tanpa ada masalah tanpa harus membahas tentang kapal ruang angkasa alien, karena itu membuat orang merasa senang dan diyakinkan, dan apa yang saya katakan adalah bahwa saya '

Descartes pernah berkata, "Karena itu, saya pikir begitu." Bagaimana dia tahu? Bagaimana jika dia tidak? Dia bisa menjadi "tidak" tapi mungkin "tidak" dapat "berpikir". Saya bahkan tidak tahu apakah saya ada. Apa sih artinya berpikir? Itu seperti kata yang digunakan orang untuk menggambarkan beberapa proses yang tampaknya berlangsung secara introspektif dan tampak seolah-olah kita, yang mungkin bahkan tidak ada, sedang membuat keputusan.

Bagaimana jika kita semua hanya bit dan byte pada beberapa mesin? Seperti si pirang atau berambut cokelat di Matrix. Ngomong-ngomong, bagaimana bisa rambut pirang atau khususnya rambut coklat disimpan dalam aliran karakter yang begitu kecil? Apakah mereka suka UTF2048? Itu semacam aliran karakter alien, tetapi tampaknya tidak terlalu banyak karakter unik. Mungkin itu semacam panggilan fungsi. Lagi pula, saya tidak yakin kami bisa menjamin apa pun. Itu semua relatif terhadap apa yang kita yakini benar.


sumber
5
"Jadi," kecuali keamanan "dalam bentuk apa pun dan" melempar destruktor "mungkin seharusnya tidak pernah digabungkan dalam kalimat yang sama. Mereka, untuk semua tujuan praktis, saling eksklusif." +1, tidak dapat berdebat dengan logika itu. Jika Anda pikir Anda bisa, Anda tidak logis.
Saya tidak melihat bagaimana ini menjawab pertanyaan awal. Masalahnya di sini adalah bahwa arg akan menghancurkan fungsi keluar tepat. Fungsi tidak akan memiliki kesempatan untuk menangkap ini. Jika fungsi telah melakukan sesuatu, ia tidak akan memiliki kesempatan untuk mengembalikannya.
Nir Friedman
2
Ya, itu kesimpulan yang benar, itu tidak menjadi kurang benar dengan menjadi tidak menyenangkan. Dalam kasus vektor, itu ilegal karena mengandung destruktor tipe yang pernah dibuang: stackoverflow.com/questions/26902006/… . Saya memahami pendekatan "berorientasi tim" Anda, tetapi terus terang itu melihatnya dari perspektif keadilan daripada kebenaran.
Nir Friedman
2
Interpretasi yang saya sukai adalah bahwa melempar destruktor adalah perilaku yang tidak terdefinisi, dan pengecualian apa yang menjamin fungsi semuanya didasarkan pada asumsi implisit bahwa tidak ada perilaku yang tidak terdefinisi terjadi (memang, segala sesuatu dalam bahasa membuat asumsi itu). Jika perilaku tidak terdefinisi dapat mencakup memformat hard drive Anda, itu pasti bisa termasuk melanggar jaminan pengecualian yang benar dari semua hal lain dalam program.
Ixrec
1
@ Ixrec Itu mungkin interpretasi pilihan Anda, tetapi melempar dari destructor tidak umum, itu hanya fakta.
Nir Friedman
-1

Secara teknis, ini mungkin dapat memberikan jaminan pengecualian yang kuat. Berarti, itu hanya dapat memberikan jaminan pengecualian yang kuat dalam kasus sepele di mana ia tidak melakukan apa pun.

Herb Sutter berbicara tentang kasus yang serupa (dan lebih intuitif) di mana fungsi mengambil argumen berdasarkan nilai yang memiliki konstruktor salinan lempar. Anda dapat memberi label fungsi semacam itu kecuali. Secara teknis, pengecualian terjadi pada "lem" antara kode panggilan dan fungsi yang dipanggil, bukan di dalam fungsi itu sendiri. Itu yang terjadi di sini juga. Karena pengecualian tidak secara teknis dilemparkan ke dalam pembaruan, Anda dapat (mungkin) berpendapat bahwa pembaruan itu sendiri tidak menghasilkan kesalahan dan karena itu dapat menawarkan jaminan pengecualian yang kuat.

Secara praktis, jika pembaruan melakukan apa pun, maka menyebutnya (dan tidak melakukan apa pun) dapat menyebabkan keadaan dunia berubah dan pengecualian dilemparkan, melanggar jaminan pengecualian yang kuat.

Nir Friedman
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
maple_shaft