Saya cenderung menambahkan banyak pernyataan ke kode C ++ saya untuk membuat debugging lebih mudah tanpa mempengaruhi kinerja rilis build. Sekarang, assert
adalah makro C murni yang dirancang tanpa memikirkan mekanisme C ++.
C ++ di sisi lain mendefinisikan std::logic_error
, yang dimaksudkan untuk dilemparkan dalam kasus di mana ada kesalahan dalam logika program (karena itu namanya). Melempar sebuah instance mungkin saja merupakan alternatif yang sempurna dan lebih C ++ untuk assert
.
Masalahnya adalah assert
dan abort
keduanya segera menghentikan program tanpa memanggil destruktor, oleh karena itu melewatkan pembersihan, sedangkan melempar pengecualian secara manual menambah biaya runtime yang tidak perlu. Salah satu cara untuk mengatasinya akan membuat makro pernyataan sendiri SAFE_ASSERT
, yang berfungsi seperti mitra C, tetapi memberikan pengecualian jika gagal.
Saya dapat memikirkan tiga pendapat tentang masalah ini:
- Tetap berpegang pada pernyataan C. Karena program segera dihentikan, tidak masalah apakah perubahan dibuka gulungannya dengan benar. Selain itu, menggunakan
#define
s di C ++ sama buruknya. - Lemparkan pengecualian dan tangkap di main () . Mengizinkan kode untuk melewati destruktor dalam keadaan program apa pun adalah praktik yang buruk dan harus dihindari dengan cara apa pun, begitu juga panggilan ke terminate (). Jika pengecualian dilemparkan, mereka harus ditangkap.
- Lempar pengecualian dan biarkan menghentikan program. Pengecualian untuk menghentikan program tidak apa-apa, dan karena itu
NDEBUG
, ini tidak akan pernah terjadi dalam build rilis. Penangkapan tidak diperlukan dan mengekspos detail implementasi kode internal kemain()
.
Apakah ada jawaban pasti untuk masalah ini? Ada referensi profesional?
Diedit: Melewati destruktor, tentu saja, bukanlah perilaku yang tidak ditentukan.
logic_error
adalah kesalahan logika. Kesalahan dalam logika program disebut bug. Anda tidak memecahkan bug dengan melemparkan pengecualian.