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 berdasarkanfilter-expression
nilai . Untuk informasi selengkapnya, lihattry-except
pernyataan.Penghentian handler, atau
__finally
blok, yang selalu dipanggil, apakah pengecualian menyebabkan penghentian atau tidak. Untuk informasi selengkapnya, lihattry-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)
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk