Özel durum belirtimleri (throw, noexcept) (C++)
Özel durum belirtimleri, programcının bir işlev tarafından yayılabilir özel durum türleriyle ilgili amacını gösteren bir C++ dil özelliğidir. Özel durum belirtimi kullanarak bir işlevin özel durum tarafından çıkabileceğini veya çıkılmayabileceğini belirtebilirsiniz. Derleyici, işleve çağrıları iyileştirmek ve beklenmeyen bir özel durum işlevden kaçarsa programı sonlandırmak için bu bilgileri kullanabilir.
C++17'den önce iki tür özel durum belirtimi vardı. Noexcept belirtimi C++11'de yeniydi. İşlevden kaçabilecek olası özel durum kümesinin boş olup olmadığını belirtir. Dinamik özel durum belirtimi veya throw(optional_type_list)
belirtimi, C++11'de kullanım dışı bırakıldı ve C++17'de kaldırıldı. Bunun dışındathrow()
, diğer adıdırnoexcept(true)
. Bu özel durum belirtimi, bir işlevden hangi özel durumların oluşturulabileceği hakkında özet bilgi sağlamak üzere tasarlanmıştır, ancak uygulamada sorunlu olduğu bulunmuştur. Bir ölçüde yararlı olduğunu kanıtlayan tek dinamik özel durum belirtimi koşulsuz throw()
belirtimdi. Örneğin, işlev bildirimi:
void MyFunction(int i) throw();
derleyiciye işlevin herhangi bir özel durum oluşturmadığını bildirir. Ancak, işlev bir özel durum oluşturursa, /std:c++14
modda bu tanımsız davranışa yol açabilir. Bu nedenle yukarıdaki yerine işlecini kullanmanızı noexcept
öneririz:
void MyFunction(int i) noexcept;
Aşağıdaki tabloda özel durum belirtimlerinin Microsoft C++ uygulaması özetlemektedir:
Özel durum belirtimi | Anlamı |
---|---|
noexcept noexcept(true) throw() |
İşlev özel durum oluşturmaz. Modunda /std:c++14 (varsayılandır) noexcept ve noexcept(true) eşdeğerdir. veya noexcept(true) std::terminate bildirilen noexcept bir işlevden özel durum oluştuğunda çağrılır. Modda olarak throw() bildirilen bir işlevden özel durum oluştuğunda /std:c++14 sonuç tanımsız davranış olur. Belirli bir işlev çağrılmaz. Bu, derleyicinin çağırmasını std::unexpected gerektiren C++14 standardının bir ayrılığıdır. Visual Studio 2017 sürüm 15.5 ve üzeri: /std:c++17 modunda , noexcept , noexcept(true) ve throw() tüm eşdeğerleridir. modunda /std:c++17 , throw() için noexcept(true) bir diğer addır. Modunda ve sonraki sürümlerde /std:c++17 , bu belirtimlerden herhangi biriyle bildirilen bir işlevden özel durum oluştuğunda, std::terminate C++17 standardının gerektirdiği şekilde çağrılır. |
noexcept(false) throw(...) Belirtim yok |
işlevi herhangi bir türde özel durum oluşturabilir. |
throw(type) |
(C++14 ve öncesi) İşlev türünde type bir özel durum oluşturabilir. Derleyici söz dizimini kabul eder, ancak olarak noexcept(false) yorumlar. Mod ve sonraki sürümlerde /std:c++17 , derleyici C5040 uyarısını verir. |
Bir uygulamada özel durum işleme kullanılıyorsa, çağrı yığınında , noexcept(true)
veya throw()
olarak işaretlenmiş noexcept
bir işlevin dış kapsamından çıkmadan önce oluşan özel durumları işleyen bir işlev olmalıdır. Özel durum oluşturan ile özel durumu işleyen arasında çağrılan işlevler , noexcept(true)
(veya throw()
modunda/std:c++17
) olarak noexcept
belirtilirse, noexcept işlevi özel durumu yaydığında program sonlandırılır.
bir işlevin özel durum davranışı aşağıdaki faktörlere bağlıdır:
Hangi dil standart derleme modunun ayarlandığı.
İşlevi C veya C++ altında derleyip derlemediğiniz.
Hangi
/EH
derleyici seçeneğini kullandığınız.Özel durum belirtimini açıkça belirtip belirtmediğiniz.
C işlevlerinde açık özel durum belirtimlerine izin verilmez. C işlevinin altında /EHsc
özel durumlar oluşturmadığı varsayılır ve , /EHa
veya /EHac
altında /EHs
yapılandırılmış özel durumlar atabilir.
Aşağıdaki tabloda, bir C++ işlevinin çeşitli derleyici özel durum işleme seçenekleri altında oluşturup oluşturmayabileceği özetlenmiştir:
Function | /EHsc |
/EHs |
/EHa |
/EHac |
---|---|---|---|---|
Özel durum belirtimi olmayan C++ işlevi | Evet | Evet | Evet | Evet |
, noexcept(true) veya throw() özel durum belirtimiyle noexcept C++ işlevi |
Hayır | Hayı | Evet | Evet |
, throw(...) veya throw(type) özel durum belirtimiyle noexcept(false) C++ işlevi |
Evet | Evet | Evet | Evet |
Örnek
// exception_specification.cpp
// compile with: /EHs
#include <stdio.h>
void handler() {
printf_s("in handler\n");
}
void f1(void) throw(int) {
printf_s("About to throw 1\n");
if (1)
throw 1;
}
void f5(void) throw() {
try {
f1();
}
catch(...) {
handler();
}
}
// invalid, doesn't handle the int exception thrown from f1()
// void f3(void) throw() {
// f1();
// }
void __declspec(nothrow) f2(void) {
try {
f1();
}
catch(int) {
handler();
}
}
// only valid if compiled without /EHc
// /EHc means assume extern "C" functions don't throw exceptions
extern "C" void f4(void);
void f4(void) {
f1();
}
int main() {
f2();
try {
f4();
}
catch(...) {
printf_s("Caught exception from f4\n");
}
f5();
}
About to throw 1
in handler
About to throw 1
Caught exception from f4
About to throw 1
in handler
Ayrıca bkz.
try
, throw
ve catch
Deyimleri (C++)
Özel durumlar ve hata işleme için modern C++ en iyi yöntemleri
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin