Bagikan melalui


Penanganan Pengecualian Terstruktur (C/C++)

Penanganan pengecualian terstruktur (SEH) adalah ekstensi Microsoft ke C dan C++ untuk menangani situasi kode luar biasa tertentu, seperti kesalahan perangkat keras, dengan anggun. Meskipun Windows dan Microsoft C++ mendukung SEH, kami sarankan Anda menggunakan penanganan pengecualian C++ standar ISO dalam kode C++. Ini membuat kode Anda lebih portabel dan fleksibel. Namun, untuk mempertahankan kode yang ada atau untuk jenis program tertentu, Anda mungkin masih harus menggunakan SEH.

Khusus Microsoft:

Tatabahasa

try-except-statement :
__try compound-statement __except ( filter-expression ) compound-statement

try-finally-statement :
__try compound-statement __finally compound-statement

Keterangan

Dengan SEH, Anda dapat memastikan bahwa sumber daya, seperti blok memori dan file, dirilis dengan benar jika eksekusi tiba-tiba berakhir. Anda juga dapat menangani masalah tertentu—misalnya, memori yang tidak mencukupi—dengan menggunakan kode terstruktur ringkas yang tidak bergantung pada goto pernyataan atau pengujian kode pengembalian yang rumit.

Pernyataan try-except dan try-finally yang dimaksud dalam artikel ini adalah ekstensi Microsoft ke bahasa C dan C++. Mereka mendukung SEH dengan memungkinkan aplikasi untuk mendapatkan kontrol atas program setelah peristiwa yang jika tidak akan mengakhiri eksekusi. Meskipun SEH berfungsi dengan file sumber C++, SEH tidak dirancang khusus untuk C++. Jika Anda menggunakan SEH dalam program C++ yang Anda kompilasi dengan menggunakan /EHa opsi atau /EHsc , destruktor untuk objek lokal dipanggil, tetapi perilaku eksekusi lainnya mungkin bukan yang Anda harapkan. Untuk ilustrasi, lihat contohnya nanti di artikel ini. Dalam kebanyakan kasus, alih-alih SEH kami sarankan Anda menggunakan penanganan pengecualian C++ standar ISO. Dengan menggunakan penanganan pengecualian C++, Anda dapat memastikan bahwa kode Anda lebih portabel, dan Anda dapat menangani pengecualian dari jenis apa pun.

Jika Anda memiliki kode C yang menggunakan SEH, Anda dapat mencampurnya dengan kode C++ yang menggunakan penanganan pengecualian C++. Untuk informasi, lihat Menangani pengecualian terstruktur di C++.

Ada dua mekanisme SEH:

  • Penangan pengecualian, atau __except blok, yang dapat merespons atau menutup pengecualian berdasarkan filter-expression nilai . Untuk informasi selengkapnya, lihat try-except pernyataan.

  • Penghentian handler, atau __finally blok, yang selalu dipanggil, apakah pengecualian menyebabkan penghentian atau tidak. Untuk informasi selengkapnya, lihat try-finally pernyataan.

Kedua jenis handler ini berbeda, tetapi terkait erat melalui proses yang dikenal sebagai melepas penat tumpukan. Ketika pengecualian terstruktur terjadi, Windows mencari handler pengecualian yang terakhir diinstal yang saat ini aktif. Handler dapat melakukan salah satu dari tiga hal:

  • Gagal mengenali pengecualian dan meneruskan kontrol ke handler lain (EXCEPTION_CONTINUE_SEARCH).

  • Kenali pengecualian tetapi tutup (EXCEPTION_CONTINUE_EXECUTION).

  • Kenali pengecualian dan tangani (EXCEPTION_EXECUTE_HANDLER).

Handler pengecualian yang mengenali pengecualian mungkin tidak ada dalam fungsi yang berjalan ketika pengecualian terjadi. Ini mungkin dalam fungsi yang jauh lebih tinggi pada tumpukan. Fungsi yang sedang berjalan dan semua fungsi lain pada bingkai tumpukan dihentikan. Selama proses ini, tumpukan tidak berlebihan. Artinya, variabel lokal non-statis dari fungsi yang dihentikan dihapus dari tumpukan.

Saat melepas tumpukan, sistem operasi memanggil penangan penghentian apa pun yang telah Anda tulis untuk setiap fungsi. Dengan menggunakan handler penghentian, Anda membersihkan sumber daya yang jika tidak akan tetap terbuka karena penghentian abnormal. Jika Anda telah memasuki bagian penting, Anda dapat keluar darinya di handler penghentian. Ketika program akan dimatikan, Anda dapat melakukan tugas housekeeping lainnya seperti menutup dan menghapus file sementara.

Langkah berikutnya

Contoh

Seperti yang dinyatakan sebelumnya, destruktor untuk objek lokal dipanggil jika Anda menggunakan SEH dalam program C++ dan mengkompilasinya dengan menggunakan /EHa opsi atau /EHsc . Namun, perilaku selama eksekusi mungkin bukan yang Anda harapkan jika Anda juga menggunakan pengecualian C++. Contoh ini menunjukkan perbedaan perilaku ini.

#include <stdio.h>
#include <Windows.h>
#include <exception>

class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\n");
    }
};

__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}

__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}

int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\n");
    }

    return 0;
}

Jika Anda menggunakan /EHsc untuk mengkompilasi kode ini tetapi makro CPPEX kontrol pengujian lokal tidak ditentukan, TestClass destruktor tidak berjalan. Keluarannya terlihat seperti:

Triggering SEH exception
Executing SEH __except block

Jika Anda menggunakan /EHsc untuk mengkompilasi kode dan CPPEX didefinisikan dengan menggunakan /DCPPEX (sehingga pengecualian C++ dilemparkan), TestClass destruktor berjalan, dan output terlihat seperti ini:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Jika Anda menggunakan /EHa untuk mengkompilasi kode, TestClass destruktor menjalankan apakah pengecualian dilemparkan menggunakan ekspresi C++ throw standar atau dengan menggunakan SEH. Artinya, apakah CPPEX didefinisikan atau tidak. Keluarannya terlihat seperti:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Untuk informasi selengkapnya, lihat /EH (Model Penanganan Pengecualian).

END Microsoft-specific

Baca juga

Penanganan pengecualian
Kata kunci
<exception>
Penanganan kesalahan dan pengecualian
Penanganan Pengecualian Terstruktur (Windows)