Bagikan melalui


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:

  1. Bagian yang dijaga dijalankan.

  2. Jika pengecualian tidak terjadi selama eksekusi bagian yang dijaga, eksekusi berlanjut pada pernyataan setelah klausul __except.

  3. 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 pernyataan try-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