Bagikan melalui


/EH (Model penanganan pengecualian)

Menentukan dukungan model penanganan pengecualian yang dihasilkan oleh pengkompilasi. Argumen menentukan apakah akan menerapkan catch(...) sintaksis ke pengecualian C++ terstruktur dan standar, apakahexternkode "C" diasumsikan untuk throw pengecualian, dan apakah akan mengoptimalkan pemeriksaan tertentunoexcept.

Sintaks

/EHa[-]
/EHs[-]
/EHc[-]
/EHr[-]

Argumen

a
Mengaktifkan unwinding tumpukan C++ standar. Menangkap pengecualian terstruktur (asinkron) dan C++ standar (sinkron) saat Anda menggunakan catch(...) sintaksis. /EHa mengambil alih argumen /EHs dan /EHc .

s
Mengaktifkan unwinding tumpukan C++ standar. Hanya menangkap pengecualian C++ standar saat Anda menggunakan catch(...) sintaksis. Kecuali /EHc ditentukan juga, pengkompilasi mengasumsikan bahwa fungsi yang dinyatakan sebagai extern "C" mungkin throw pengecualian C++.

c
Ketika digunakan dengan /EHs, pengkompilasi mengasumsikan bahwa fungsi yang dinyatakan sebagai extern "C" tidak pernah throw pengecualian C++. Ini tidak berpengaruh ketika digunakan dengan (yaitu, /EHca setara /EHadengan /EHa ). /EHc diabaikan jika /EHs atau /EHa tidak ditentukan.

r
Memberi tahu pengkompilasi untuk selalu menghasilkan pemeriksaan penghentian runtime untuk semua noexcept fungsi. Secara default, pemeriksaan noexcept runtime dapat dioptimalkan jika pengkompilasi menentukan fungsi hanya memanggil fungsi non-ingthrow. Opsi ini memberikan kesuaian C++ yang ketat dengan biaya beberapa kode tambahan. /EHr diabaikan jika /EHs atau /EHa tidak ditentukan.

-
Menghapus argumen opsi sebelumnya. Misalnya, /EHsc- ditafsirkan sebagai /EHs /EHc-, dan setara dengan /EHs.

/EH argumen dapat ditentukan secara terpisah atau digabungkan, dalam urutan apa pun. Jika lebih dari satu instans argumen yang sama ditentukan, yang terakhir akan mengambil alih instans sebelumnya. Misalnya, /EHr- /EHc /EHs sama /EHscr-dengan , dan /EHscr- /EHr memiliki efek yang sama dengan /EHscr.

Keterangan

Perilaku penanganan pengecualian default

Pengompilasi selalu menghasilkan kode yang mendukung penanganan pengecualian terstruktur asinkron (SEH). Secara default (yaitu, jika tidak ada /EHscopsi , /EHs, atau /EHa yang ditentukan), pengkompilasi mendukung handler dalam klausa SEH C++ catch(...) asli. Namun, ini juga menghasilkan kode yang hanya sebagian mendukung pengecualian C++. Kode unwinding pengecualian default tidak menghancurkan objek C++ otomatis di luar try blok yang keluar dari cakupan karena pengecualian. Kebocoran sumber daya dan perilaku yang tidak terdefinisi dapat mengakibatkan ketika pengecualian C++ adalah thrown.

Penanganan pengecualian C++ standar

Dukungan kompilator penuh untuk model penanganan pengecualian C++ Standar yang dengan aman melepas objek tumpukan yang diperlukan (disarankan /EHsc ), /EHs, atau /EHa.

Jika Anda menggunakan /EHs atau /EHsc, maka klausul Anda catch(...) tidak catch memiliki pengecualian terstruktur asinkron. Setiap pelanggaran akses dan pengecualian terkelola System.Exception tidak tertangkap. Dan, objek dalam cakupan ketika pengecualian asinkron terjadi tidak dihancurkan, bahkan jika kode menangani pengecualian asinkron. Perilaku ini adalah argumen untuk membiarkan pengecualian terstruktur tidak tertangani. Sebagai gantinya, pertimbangkan pengecualian ini fatal.

Ketika Anda menggunakan /EHs atau /EHsc, pengkompilasi mengasumsikan bahwa pengecualian hanya dapat terjadi pada throw pernyataan atau pada panggilan fungsi. Asumsi ini memungkinkan pengkompilasi untuk menghilangkan kode untuk melacak masa pakai banyak objek yang dapat dilepaskan, yang dapat secara signifikan mengurangi ukuran kode. Jika Anda menggunakan /EHa, gambar yang dapat dieksekusi mungkin lebih besar dan lebih lambat, karena pengkompilasi tidak mengoptimalkan try blok secara agresif. Ini juga meninggalkan filter pengecualian yang secara otomatis membersihkan objek lokal, bahkan jika pengkompilasi tidak melihat kode apa pun yang dapat throw pengecualian C++.

Penanganan pengecualian C++ terstruktur dan standar

Opsi /EHa kompilator memungkinkan pelepasan tumpukan yang aman untuk pengecualian asinkron dan pengecualian C++. Ini mendukung penanganan pengecualian C++ standar dan terstruktur dengan menggunakan klausa C++ catch(...) asli. Untuk menerapkan SEH tanpa menentukan /EHa, Anda dapat menggunakan __trysintaks , __except, dan __finally . Untuk informasi selengkapnya, lihat Penanganan pengecualian terstruktur.

Penting

Menentukan /EHa dan trymelakukan ing untuk menangani semua pengecualian dengan menggunakan catch(...) bisa berbahaya. Dalam kebanyakan kasus, pengecualian asinkron tidak dapat dipulihkan dan harus dianggap fatal. Menangkap mereka dan melanjutkan dapat menyebabkan kerusakan proses dan menyebabkan bug yang sulit ditemukan dan diperbaiki.

Meskipun Dukungan SEHWindows dan Visual C++, kami sangat menyarankan Agar Anda menggunakan penanganan pengecualian C++ standar ISO (/EHsc atau /EHs). Ini membuat kode Anda lebih portabel dan fleksibel. Mungkin masih ada kalanya Anda harus menggunakan SEH dalam kode warisan atau untuk jenis program tertentu. Diperlukan dalam kode yang dikompilasi untuk mendukung runtime bahasa umum (/clr), misalnya. Untuk informasi selengkapnya, lihat Penanganan pengecualian terstruktur.

Kami menyarankan agar Anda tidak pernah menautkan file objek yang dikompilasi menggunakan /EHa ke file yang dikompilasi menggunakan /EHs atau /EHsc dalam modul yang dapat dieksekusi yang sama. Jika Anda harus menangani pengecualian asinkron dengan menggunakan /EHa di mana saja dalam modul Anda, gunakan /EHa untuk mengompilasi semua kode dalam modul. Anda dapat menggunakan sintaks penanganan pengecualian terstruktur dalam modul yang sama dengan kode yang dikompilasi dengan menggunakan /EHs. Namun, Anda tidak dapat mencampur SEH sintaks dengan C++ try, throw, dan catch dalam fungsi yang sama.

Gunakan /EHa jika Anda ingin catch pengecualian yang dimunculkan oleh sesuatu selain throw. Contoh ini menghasilkan dan catches pengecualian terstruktur:

// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;

void fail()
{
    // generates SE and attempts to catch it using catch(...)
    try
    {
        int i = 0, j = 1;
        j /= i;   // This will throw a SE (divide by zero).
        printf("%d", j);
    }
    catch(...)
    {
        // catch block will only be executed under /EHa
        cout << "Caught an exception in catch(...)." << endl;
    }
}

int main()
{
    __try
    {
        fail();
    }

    // __except will only catch an exception here
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // if the exception was not caught by the catch(...) inside fail()
        cout << "An exception was caught in __except." << endl;
    }
}

Penanganan pengecualian di bawah /clr

Opsi /clr menyiratkan /EHa (yaitu, /clr /EHa berlebihan). Pengkompilasi menghasilkan kesalahan jika /EHs atau /EHsc digunakan setelah /clr. Pengoptimalan tidak memengaruhi perilaku ini. Ketika pengecualian tertangkap, pengkompilasi memanggil destruktor kelas untuk objek apa pun yang berada dalam cakupan yang sama dengan pengecualian. Jika pengecualian tidak tertangkap, destruktor tersebut tidak dijalankan.

Untuk informasi tentang pembatasan penanganan pengecualian di bawah /clr, lihat _set_se_translator.

Pemeriksaan pengecualian runtime

Opsi memaksa /EHr pemeriksaan penghentian runtime di semua fungsi yang memiliki noexcept atribut . Secara default, pemeriksaan runtime dapat dioptimalkan jika back-end kompilator menentukan bahwa fungsi hanya memanggil fungsi non-ingthrow. Fungsi non-ingthrow adalah fungsi apa pun yang memiliki atribut yang menentukan tidak ada pengecualian mungkin thrown. Fungsi tersebut mencakup fungsi bertanda noexcept, , __declspec(nothrow)throw(), dan, kapan /EHc ditentukan, extern "C" fungsi. Fungsi non-ingthrow juga mencakup apa pun yang telah ditentukan pengkompilasi adalah non-ingthrow oleh inspeksi. Anda dapat secara eksplisit mengatur perilaku default dengan menggunakan /EHr-.

Atribut non-ingthrow bukan jaminan bahwa pengecualian tidak dapat n throwoleh fungsi. Tidak seperti perilaku noexcept fungsi, pengkompilasi MSVC mempertimbangkan pengecualian thrown oleh fungsi yang dideklarasikan menggunakan throw(), , __declspec(nothrow)atau extern "C" sebagai perilaku yang tidak ditentukan. Fungsi yang menggunakan ketiga atribut deklarasi ini tidak memberlakukan pemeriksaan penghentian runtime untuk pengecualian. Anda dapat menggunakan /EHr opsi untuk membantu Anda mengidentifikasi perilaku yang tidak terdefinisi ini, dengan memaksa pengkompilasi untuk menghasilkan pemeriksaan runtime untuk pengecualian yang tidak tertangani yang lolos dari noexcept fungsi.

Mengatur opsi di Visual Studio atau secara terprogram

Untuk mengatur opsi pengkompilasi ini di lingkungan pengembangan Visual Studio

  1. Buka kotak dialog Halaman Properti proyek. Untuk detailnya, lihat Mengatur pengkompilasi C++ dan membuat properti di Visual Studio.

  2. Pilih Properti>Konfigurasi C/C++>Pembuatan Kode.

  3. Ubah properti Aktifkan Pengecualian C++.

    Atau, atur Aktifkan Pengecualian C++ ke Tidak, lalu pada halaman properti Baris Perintah, dalam kotak Opsi Tambahan, tambahkan opsi pengkompilasi.

Untuk mengatur opsi pengkompilasi ini secara terprogram

Baca juga

Opsi Pengkompilasi MSVC
Sintaks baris perintah MSVC Compiler
Penanganan kesalahan dan pengecualian
Spesifikasi pengecualian (throw)
Penanganan Pengecualian Terstruktur (C/C++)