try-except
pernyataan
Pernyataan ini try-except
adalah ekstensi khusus Microsoft yang mendukung penanganan pengecualian terstruktur dalam bahasa C dan C++.
// . . .
__try {
// guarded code
}
__except ( /* filter expression */ ) {
// termination code
}
// . . .
Tatabahasa
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Keterangan
Pernyataan ini try-except
adalah ekstensi Microsoft untuk bahasa C dan C++. Ini memungkinkan aplikasi target untuk mendapatkan kontrol ketika peristiwa terjadi yang biasanya menghentikan eksekusi program. Peristiwa tersebut disebut pengecualian terstruktur, atau pengecualian singkatnya. Mekanisme yang berkaitan dengan pengecualian ini disebut penanganan pengecualian terstruktur (SEH).
Untuk informasi terkait, lihat pernyataan try-finally.
Pengecualian mungkin berbasis perangkat keras atau berbasis perangkat lunak. Penanganan pengecualian terstruktur berguna bahkan ketika aplikasi tidak dapat sepenuhnya pulih dari pengecualian perangkat keras atau perangkat lunak. SEH memungkinkan untuk menampilkan informasi kesalahan dan menjebak status internal aplikasi untuk membantu mendiagnosis masalah. Ini sangat berguna untuk masalah terputus-terputus-terputus yang tidak mudah untuk diproduksi ulang.
Catatan
Penanganan pengecualian terstruktur berfungsi dengan Win32 untuk file sumber C dan C++. Namun, ini tidak dirancang khusus untuk C++. Anda dapat memastikan bahwa kode Anda lebih portabel dengan menggunakan penanganan pengecualian C++. Selain itu, penanganan pengecualian C++ lebih fleksibel, karena dapat menangani pengecualian dari jenis apa pun. Untuk program C++, kami sarankan Anda menggunakan penanganan pengecualian C++ asli: coba, tangkap, dan lempar pernyataan.
Pernyataan majemuk setelah __try
klausul adalah isi atau bagian yang dijaga. Ekspresi __except
juga dikenal sebagai ekspresi filter . Nilainya menentukan bagaimana pengecualian ditangani. Pernyataan majemuk setelah __except
klausul adalah handler pengecualian. Handler menentukan tindakan yang harus diambil jika pengecualian dinaikkan selama eksekusi bagian isi. Eksekusi berlangsung sebagai berikut:
Bagian yang dijaga dijalankan.
Jika pengecualian tidak terjadi selama eksekusi bagian yang dijaga, eksekusi berlanjut pada pernyataan setelah klausul
__except
.Jika pengecualian terjadi selama eksekusi bagian yang dijaga, atau dalam rutinitas panggilan bagian yang dijaga,
__except
ekspresi dievaluasi. Ada tiga nilai yang memungkinkan:EXCEPTION_CONTINUE_EXECUTION
(-1) Pengecualian diberhentikan. Lanjutkan eksekusi pada titik di mana pengecualian terjadi.EXCEPTION_CONTINUE_SEARCH
(0) Pengecualian tidak dikenali. Lanjutkan mencari penangan di tumpukan, pertama yang berisi pernyataantry-except
, lalu penangan dengan urutan tertinggi berikutnya.EXCEPTION_EXECUTE_HANDLER
(1) Pengecualian dikenali. Transfer kontrol ke handler pengecualian dengan menjalankan__except
pernyataan senyawa, lalu lanjutkan eksekusi setelah__except
blok.
Ekspresi __except
dievaluasi sebagai ekspresi C. Ini terbatas pada satu nilai, operator ekspresi kondisional, atau operator koma. Jika diperlukan pemrosesan yang lebih ekstensif, ekspresi dapat memanggil sebuah rutin yang mengembalikan salah satu dari tiga nilai yang tercantum di atas.
Setiap aplikasi dapat memiliki handler pengecualiannya sendiri.
Tidak valid untuk melompat ke dalam pernyataan __try
, tetapi valid untuk melompat keluar dari satu pernyataan. Handler pengecualian tidak dipanggil jika proses dihentikan di tengah menjalankan try-except
pernyataan.
Untuk kompatibilitas dengan versi sebelumnya, _try, _except, dan _leave adalah sinonim untuk __try
, __except
, dan __leave
kecuali opsi pengompilasi /Za (Nonaktifkan ekstensi bahasa) ditentukan.
Kata kunci __leave
Kata __leave
kunci hanya valid dalam bagian yang dijaga dari pernyataan try-except
, dan efeknya adalah melompat ke akhir bagian yang dijaga. Eksekusi berlanjut pada pernyataan pertama setelah handler pengecualian.
Pernyataan goto
juga dapat melompat keluar dari bagian yang dijaga, dan tidak menurunkan performa seperti yang dilakukan dalam pernyataan try-finally . Itu karena stack unwinding tidak terjadi. Namun, kami sarankan __leave
Anda menggunakan kata kunci daripada goto
pernyataan. Alasannya adalah karena Anda cenderung tidak membuat kesalahan pemrograman jika bagian yang dijaga besar atau kompleks.
Fungsi intrinsik penanganan pengecualian terstruktur
Penanganan pengecualian terstruktur menyediakan dua fungsi intrinsik yang tersedia untuk digunakan dengan try-except
pernyataan: GetExceptionCode dan GetExceptionInformation.
GetExceptionCode
mengembalikan kode (bilangan bulat 32-bit) dari pengecualian.
Fungsi intrinsik GetExceptionInformation
mengembalikan penunjuk ke struktur EXCEPTION_POINTERS yang berisi informasi tambahan tentang pengecualian. Melalui pointer ini, Anda dapat mengakses status komputer yang ada pada saat pengecualian perangkat keras. Strukturnya adalah sebagai berikut:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
Jenis pointer PEXCEPTION_RECORD
dan didefinisikan dalam file <include winnt.h>, dan _EXCEPTION_RECORD
dan _CONTEXT
didefinisikan dalam file <include excpt.h PCONTEXT
>
Anda dapat menggunakan GetExceptionCode
dalam handler pengecualian. Namun, Anda hanya dapat menggunakan GetExceptionInformation
dalam ekspresi filter pengecualian. Informasi yang ditujukan umumnya ada di tumpukan dan tidak lagi tersedia ketika kontrol ditransfer ke handler pengecualian.
Fungsi intrinsik AbnormalTermination tersedia dalam handler penghentian. Ini mengembalikan 0 jika isi pernyataan try-finally berakhir secara berurutan. Dalam semua kasus lain, mengembalikan 1.
<excpt.h> mendefinisikan beberapa nama alternatif untuk intrinsik ini:
GetExceptionCode
setara dengan _exception_code
GetExceptionInformation
setara dengan _exception_info
AbnormalTermination
setara dengan _abnormal_termination
Contoh
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION)
{
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try
{
puts("in try");
__try
{
puts("in try");
*p = 13; // causes an access violation exception;
}
__finally
{
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}
__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
puts("in except");
}
puts("world");
}
Output
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
Lihat juga
Menulis handler pengecualian
Penanganan Pengecualian Terstruktur (C/C++)
Kata kunci
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