Bagikan melalui


Menulis filter pengecualian

Anda dapat menangani pengecualian baik dengan melompat ke tingkat handler pengecualian atau dengan melanjutkan eksekusi. Alih-alih menggunakan kode handler pengecualian untuk menangani pengecualian dan jatuh, Anda dapat menggunakan ekspresi filter untuk membersihkan masalah. Kemudian, dengan mengembalikan EXCEPTION_CONTINUE_EXECUTION (-1), Anda dapat melanjutkan alur normal tanpa menghapus tumpukan.

Catatan

Beberapa pengecualian tidak dapat dilanjutkan. Jika filter mengevaluasi ke -1 untuk pengecualian seperti itu, sistem akan menimbulkan pengecualian baru. Saat Anda memanggil RaiseException, Anda menentukan apakah pengecualian akan berlanjut.

Misalnya, kode berikut menggunakan panggilan fungsi dalam ekspresi filter : fungsi ini menangani masalah lalu mengembalikan -1 untuk melanjutkan alur kontrol normal:

// exceptions_Writing_an_Exception_Filter.cpp
#include <windows.h>
int main() {
   int Eval_Exception( int );

   __try {}

   __except ( Eval_Exception( GetExceptionCode( ))) {
      ;
   }

}
void ResetVars( int ) {}
int Eval_Exception ( int n_except ) {
   if ( n_except != STATUS_INTEGER_OVERFLOW &&
      n_except != STATUS_FLOAT_OVERFLOW )   // Pass on most exceptions
   return EXCEPTION_CONTINUE_SEARCH;

   // Execute some code to clean up problem
   ResetVars( 0 );   // initializes data to 0
   return EXCEPTION_CONTINUE_EXECUTION;
}

Ada baiknya menggunakan panggilan fungsi dalam ekspresi filter setiap kali filter perlu melakukan apa pun yang kompleks. Mengevaluasi ekspresi menyebabkan eksekusi fungsi, dalam hal ini, Eval_Exception.

Perhatikan penggunaan GetExceptionCode untuk menentukan pengecualian. Fungsi ini harus dipanggil di dalam ekspresi __except filter pernyataan. Eval_Exception tidak dapat memanggil GetExceptionCode, tetapi harus memiliki kode pengecualian yang diteruskan ke dalamnya.

Handler ini meneruskan kontrol ke handler lain kecuali pengecualiannya adalah bilangan bulat atau floating-point overflow. Jika ya, handler memanggil fungsi (ResetVars hanya contoh, bukan fungsi API) untuk mengatur ulang beberapa variabel global. __except Blok pernyataan, yang dalam contoh ini kosong, tidak pernah dapat dijalankan karena Eval_Exception tidak pernah mengembalikan EXCEPTION_EXECUTE_HANDLER (1).

Menggunakan panggilan fungsi adalah teknik tujuan umum yang baik untuk menangani ekspresi filter yang kompleks. Dua fitur bahasa C lainnya yang berguna adalah:

  • Operator bersyarah

  • Operator koma

Operator bersyarah sering berguna di sini. Ini dapat digunakan untuk memeriksa kode pengembalian tertentu dan kemudian mengembalikan salah satu dari dua nilai yang berbeda. Misalnya, filter dalam kode berikut mengenali pengecualian hanya jika pengecualiannya adalah STATUS_INTEGER_OVERFLOW:

__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ? 1 : 0 ) {

Tujuan operator bersyukur dalam hal ini terutama untuk memberikan kejelasan, karena kode berikut menghasilkan hasil yang sama:

__except( GetExceptionCode() == STATUS_INTEGER_OVERFLOW ) {

Operator kondisional lebih berguna dalam situasi di mana Anda mungkin ingin filter dievaluasi ke -1, EXCEPTION_CONTINUE_EXECUTION.

Operator koma memungkinkan Anda menjalankan beberapa ekspresi secara berurutan. Kemudian mengembalikan nilai ekspresi terakhir. Misalnya, kode berikut menyimpan kode pengecualian dalam variabel lalu mengujinya:

__except( nCode = GetExceptionCode(), nCode == STATUS_INTEGER_OVERFLOW )

Baca juga

Menulis handler pengecualian
Penanganan Pengecualian Terstruktur (C/C++)