/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, apakahextern kode "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 /EHa
dengan /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-throwing. 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 /EHsc
opsi , /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++ dilemparkan.
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 __try
sintaks , __except
, dan __finally
. Untuk informasi selengkapnya, lihat Penanganan pengecualian terstruktur.
Penting
Menentukan /EHa
dan mencoba 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 menangkap 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-throwing . Fungsi non-throwing adalah fungsi apa pun yang memiliki atribut yang menentukan tidak ada pengecualian yang dapat dilemparkan. Fungsi tersebut mencakup fungsi bertanda noexcept
, , __declspec(nothrow)
throw()
, dan, kapan /EHc
ditentukan, extern "C"
fungsi. Fungsi non-throwing juga mencakup apa pun yang telah ditentukan pengkompilasi tidak dilemparkan oleh inspeksi. Anda dapat secara eksplisit mengatur perilaku default dengan menggunakan /EHr-
.
Atribut non-throwing bukan jaminan bahwa pengecualian tidak dapat dilemparkan oleh fungsi. Tidak seperti perilaku noexcept
fungsi, pengkompilasi MSVC mempertimbangkan pengecualian yang dilemparkan oleh fungsi yang dinyatakan 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
Buka kotak dialog Halaman Properti proyek. Untuk detailnya, lihat Mengatur pengkompilasi C++ dan membuat properti di Visual Studio.
Pilih Properti>Konfigurasi C/C++>Pembuatan Kode.
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
- Lihat ExceptionHandling.
Lihat juga
Opsi Pengkompilasi MSVC
Sintaks baris perintah MSVC Compiler
Penanganan kesalahan dan pengecualian
Spesifikasi pengecualian (throw)
Penanganan Pengecualian Terstruktur (C/C++)