- Asla atmayacağını bildiğim, ancak derleyicinin bunu kendi başına belirleyemediği birçok işlev örneği var. Tüm bu durumlarda işlev beyanına istisna eklemem gerekir mi?
noexcept
işlevler arayüzünün bir parçası olduğu için zor. Özellikle bir kitaplık yazıyorsanız, istemci kodunuz noexcept
özelliğe bağlı olabilir . Varolan kodu kırabileceğiniz için daha sonra değiştirmek zor olabilir. Yalnızca uygulamanız tarafından kullanılan kodu uygularken bu daha az endişe verici olabilir.
Eğer atamadığınız bir fonksiyonunuz varsa, kendinize bunun kalmak isteyip istemeyeceğini noexcept
veya gelecekteki uygulamaları kısıtlayacak mı diye sorun. Örneğin, kural dışı durumları (ör. Birim testleri için) atarak yasadışı argümanlarda hata denetimi yapmak isteyebilirsiniz veya kural dışı durum belirtimini değiştirebilecek diğer kitaplık koduna güvenebilirsiniz. Bu durumda, muhafazakar olmak ve atlamak daha güvenlidirnoexcept
.
Öte yandan, fonksiyonun asla atmaması gerektiğinden eminseniz ve spesifikasyonun bir parçası olduğu doğruysa, beyan etmelisiniz noexcept
. Ancak, derleyicinin noexcept
uygulamanızın değişmesi durumunda ihlalleri tespit edemeyeceğini unutmayın.
- Hangi durumlar için noexcept kullanımı konusunda daha dikkatli olmalıyım ve hangi durumlar için zımni noexcept (false) ile kaçabilirim?
Konsantre olmanız gereken dört işlev sınıfı vardır, çünkü muhtemelen en büyük etkiye sahip olacaktır:
- taşıma işlemleri (atama işlecini taşıma ve yapıcıları taşıma)
- takas işlemleri
- bellek dağıtıcıları (operatör silme, operatör silme [])
- yıkıcılar (
noexcept(true)
siz bunları yapmadığınız sürece bunlar dolaylı olarak noexcept(false)
)
Bu işlevler genellikle olmalıdır noexcept
ve büyük olasılıkla kütüphane uygulamaları bu noexcept
özellikten yararlanabilir. Örneğin, std::vector
güçlü istisna garantilerinden ödün vermeden fırlatma hareketi hareketlerini kullanabilir. Aksi takdirde, (C ++ 98'de olduğu gibi) kopyalama öğelerine geri dönmesi gerekecektir.
Bu tür bir optimizasyon algoritmik düzeydedir ve derleyici optimizasyonlarına dayanmaz. Özellikle öğelerin kopyalanması pahalıysa, önemli bir etkisi olabilir.
- NoExcept kullandıktan sonra ne zaman gerçekçi bir performans artışı gözlemlemeyi bekleyebilirim? Özellikle, bir C ++ derleyicisinin noexcept eklendikten sonra daha iyi makine kodu üretebildiği bir kod örneği verin.
noexcept
İstisna belirtimine karşı olmayan avantajı veya throw()
standardın, çözücüler yığın çözme konusunda daha fazla özgürlüğe izin vermesidir. throw()
Durumda bile , derleyici yığını tamamen gevşetmelidir (ve nesne yapılarının tam tersi sırayla yapmalıdır).
Öte noexcept
yandan, bunu yapmak gerekli değildir. Yığının açılmasına gerek yoktur (ancak derleyicinin bunu yapmasına izin verilir). Bu özgürlük, yığının her zaman çözülme yükünü azalttığı için daha fazla kod optimizasyonuna izin verir.
İstisna, yığın çözme ve performans ile ilgili soru , yığın çözme gerektiğinde ek yük hakkında daha fazla ayrıntıya girer.
Ayrıca Scott Meyers'ın "Effective Modern C ++", "Item 14: İstisnaları yaymayacakları sürece istisnasız işlevleri beyan etmeleri" kitabını tavsiye ederim.
move_if_nothrow
(veya whatchamacallit) kod, istisnai bir taşıma kaseti varsa performansta bir iyileşme görecektir.