Yayın sürümlerinde iddialar varsa


21

assertC ++ 'da varsayılan davranış, sürüm derlemeleri hiçbir şey yapmaktır. Bunun performans nedeniyle yapıldığını ve belki de kullanıcıların kötü hata mesajları görmesini önlemek için yapıldığını düşünüyorum.

Ancak, bir assertişten çıkarılmış ancak devre dışı bırakılan durumların daha da zahmetli olduğunu iddia ediyorum çünkü uygulama muhtemelen bazı değişmezler kırıldığı için hatta daha da kötü bir şekilde çökecektir.

Ek olarak, benim için performans argümanı sadece ölçülebilir bir problem olduğunda önemlidir. Kodumdaki çoğu assertkod daha karmaşık değil

assert(ptr != nullptr);

çoğu kod üzerinde küçük bir etkisi olacaktır.

Bu beni şu soruya yönlendiriyor: Sürüm sürümlerinde iddialar (belirli bir uygulama değil, kavram anlamına gelir) aktif olmalı mı? Neden olmasın)?

Lütfen bu sorunun sürüm derlemelerinde ( #undef _NDEBUGkendinden tanımlı bir iddia uygulaması gibi veya kullanarak) eklerin nasıl etkinleştirileceği ile ilgili olmadığını unutmayın . Ayrıca, üçüncü taraf / standart kütüphane kodunda değil benim tarafımdan kontrol edilen kodda eklerin etkinleştirilmesi ile ilgilidir.


Sağlık pazarında, müşteri sitelerine hastane bilgi sistemlerinin hata ayıklama sürümünü kuran küresel bir oyuncu tanıyorum. Orada da C ++ hata ayıklama kitaplıklarını kurmak için Microsoft ile özel bir anlaşmaları vardı. Ürünlerinin kalitesi ...
Bernhard Hiller

3
Gider Eski bir deyiş vardır "iddialarını kaldırarak biraz limanda uygulamasına hayat ceket giyen, ancak daha sonra arkasında can yeleği bırakmak gibi olduğunda açık okyanusta için gemi yaprakları" ( wiki.c2.com/?AssertionsAsDefensiveProgramming ) . Ben şahsen varsayılan olarak sürüm derlemeleri onları etkin tutmak. Ne yazık ki, bu uygulama C ++ dünyasında çok yaygın değildir, ancak en azından ünlü C ++ kıdemli James Kanze, her zaman sürüm sürümlerinde iddiaları koruma lehine tartışırdı: stackoverflow.com/a/12162195/3313064
Christian Hackl

Yanıtlar:


20

Klasik assert, C ++ 'dan değil, eski standart C kütüphanesinden bir araçtır. En azından geriye dönük uyumluluk nedeniyle C ++ ile kullanılabilir.

Eldeki C standart kütüphanelerinin kesin bir zaman çizelgesine sahip değilim, ancak assertK&R C'nin (1978 civarında) devreye girmesinden kısa bir süre sonra mevcut olduğundan eminim . Klasik C'de, sağlam programlar yazmak için, NULL işaretçi testleri ve dizi sınırları kontrolünün eklenmesi, C ++ 'dan daha sık yapılmalıdır. NULL işaretçi testlerinin brütünden, işaretçiler yerine referanslar ve / veya akıllı işaretçiler kullanılarak kaçınılabilir ve std::vectordizi sınırları denetimi genellikle gereksizdir. Dahası, 1980'deki performans kesinlikle bugünden çok daha önemliydi. Bu yüzden "assert" in varsayılan olarak sadece hata ayıklama yapılarında etkin olacak şekilde tasarlanmasının nedeni budur.

Ayrıca, üretim kodundaki gerçek hata işleme için, sadece bir durumu veya değişmezi test eden ve koşul yerine getirilmezse programı çökerten bir işlev çoğu durumda yeterince esnek değildir. Hata ayıklama için bu muhtemelen tamamdır, çünkü programı çalıştıran ve hatayı gözlemleyen kişi tipik olarak ne olduğunu analiz etmek için bir hata ayıklayıcıya sahiptir. Bununla birlikte, üretim kodu için, mantıklı bir çözümün,

  • bazı koşulları test eder (ve durumun başarısız olduğu kapsamda yürütmeyi durdurur)

  • koşulun gerçekleşmemesi durumunda net bir hata mesajı verir

  • dış kapsamın hata mesajını almasına izin verir ve belirli bir iletişim kanalına verir. Bu kanal stderr, standart bir günlük dosyası, GUI programındaki bir mesaj kutusu, genel bir hata işleme geri araması, ağ özellikli bir hata kanalı veya belirli bir yazılım parçasına en uygun olan şey olabilir.

  • her durumda temel kapsamın dış kapsamının, programın zarif bir şekilde sona ermesi veya devam etmesi gerekip gerekmediğine karar vermesini sağlar.

(Tabii ki, yerine getirilmemiş bir durum durumunda programı hemen sonlandırmanın tek mantıklı seçenek olduğu durumlar da vardır, ancak bu gibi durumlarda, sadece bir hata ayıklama derlemesinde değil, bir sürüm derlemesinde de olması gerekir).

Klasik assertbu özellikleri sağlamadığından, bir sürüm oluşturma için uygun değildir, sürümün bir kişinin üretime dağıttığı varsayılır.

Şimdi C standart lib'de neden bu tür bir esneklik sağlayan böyle bir fonksiyon veya mekanizma olmadığını sorabilirsiniz. Aslında, C ++ 'da, tüm bu özelliklere (ve daha fazlasına) sahip standart bir mekanizma vardır ve bunu biliyorsunuz: istisnalar denir .

Bununla birlikte, C'de, programlama dilinin bir parçası olarak istisnaların bulunmaması nedeniyle, bahsedilen tüm özelliklerle hata işleme için iyi, genel amaçlı bir standart mekanizma uygulamak zordur. Bu nedenle, çoğu C programının dönüş kodları veya "git" veya "uzun atlama" veya bunların bir karışımı ile kendi hata işleme mekanizmaları vardır. Bunlar genellikle belirli türdeki programlara uyan pragmatik çözümlerdir, ancak C standart kütüphanesine sığacak kadar "genel amaç" değildir.


Ah, C mirasını tamamen unuttum (sonuçta #include <cassert>). Bu tamamen mantıklı.
Kimse

1
Tüm bu cevaba tamamen katılmıyorum. Uygulamanızın kaynak kodunun buggy olduğunu keşfettiğinde bir istisna atmak, Java gibi dillerde daha iyi yapamayan ancak C ++ dilinde bu durumda böyle bir durumda programı hemen sonlandıran son çözümdür. Sen neden gevşemek yığını istemiyoruz herhangi başka işlemler bu noktada yürütülecek. Hatalı bir program, dosyalara, veritabanlarına veya ağ soketlerine muhtemelen bozuk veriler yazabilir. Sadece ASAP'yi çökertin (ve muhtemelen işlemi harici bir mekanizma ile yeniden başlatın).
Christian Hackl

1
@ChristianHackl: Bir programı sonlandırmanın tek geçerli seçenek olduğu durumlar olduğunu kabul ediyorum, ancak daha sonra yayın modunda da olmalı ve bunun assertiçin de yanlış bir araç (bir istisna atmak da yanlış tepki olabilir) ). Bununla birlikte, gerçekte assertC ++ 'da bugün istisnalar kullanacak olan C testlerinde de kullanıldığından eminim .
Doc Brown

15

Kendinizi bir sürümde eklerin etkinleştirilmesini diliyorsanız, yanlış işi yapmasını istediniz.

Varsayımların amacı, bir sürümde etkinleştirilmemesidir. Bu, geliştirme sırasında değişmezlerin, aksi takdirde iskele kodu olması gereken kodla test edilmesine izin verir. Yayınlanmadan önce kaldırılması gereken kod.

Sürüm sırasında bile test edilmesi gerektiğini düşündüğünüz bir şey varsa, bunu test eden bir kod yazın. If throwYapı çok iyi çalışıyor. Diğer atışlardan farklı bir şey söylemek istiyorsanız, söylemek istediklerinizi söyleyen açıklayıcı bir istisna kullanın.

Ekleri kullanma şeklinizi değiştiremezsiniz. Bunu yapmak size faydalı bir şey getirmez, beklentilere karşı gelir ve iddiaların ne yapmak istediğini yapmak için hiçbir şekilde temiz bir yol bırakmaz. Bir sürümde etkin olmayan testleri ekleyin.

Belirli bir iddia uygulamasından değil, iddia kavramından bahsediyorum. İddiaları kötüye kullanmak ya da okuyucuları karıştırmak istemiyorum. İlk etapta neden böyle olduğunu sormak istedim. Neden ek release_assert yok? Buna gerek yok mu? Serbest bırakılmada iddia edilen engellemenin ardındaki mantık nedir? - Hiç kimse

Neden relase_assert yok? Açıkçası çünkü iddialar üretim için yeterince iyi değil. Evet bir ihtiyaç var ama bu ihtiyacı iyi karşılayan hiçbir şey yok. Oh emin kendi tasarım. Mekanik olarak throwIf fonksiyonunuzun bir boole ve atmak için bir istisnaya ihtiyacı vardır. Ve bu ihtiyaçlarınızı karşılayabilir. Ama tasarımı gerçekten kısıtlıyorsunuz. Bu yüzden dil kütüphanenizde istisna atma sistemi gibi pişmiş bir iddia olmadığı beni şaşırtmıyor. Kesinlikle yapamazsınız. Diğerleri var . Ancak işlerin yanlış gittiği durumla uğraşmak çoğu program için% 80 iştir. Ve şimdiye kadar hiç kimse bize iyi bir boyut göstermedi, tüm çözümlere uyuyor. Bu vakalarla etkili bir şekilde mücadele etmek karmaşıklaşabilir. İhtiyacımızın altına düşen konserve bir release_assert sistemimiz olsaydı, bence iyi olandan daha fazla zarar verirdi. Bu sorun hakkında düşünmek zorunda kalmayacağınız anlamına gelen iyi bir soyutlama istiyorsunuz. Ben de istiyorum ama henüz orada değilmiş gibi görünmüyor.

İfadeler neden serbest bırakılır? Ekler, iskele kodu çağının yüksekliğinde oluşturuldu. Kod kaldırmamız gerekti, çünkü üretimde istemediğimizi biliyorduk ama hataları bulmamıza yardımcı olmak için geliştirme aşamasında koşmak istediğimizi biliyorduk. Ekler if (DEBUG), kodu bırakıp devre dışı bırakmamıza izin veren desene daha temiz bir alternatifti . Bu, test kodunu üretim kodundan ayırmanın ana yolu olarak birim testinin başlamasından önceydi. Günümüzde, beklentiler açıklığa kavuşturmak ve hala birim testten daha iyi yaptıkları vakaları kapsamak için uzman birim uzmanları bile bugün kullanılmaktadır.

Neden sadece hata ayıklama kodunu üretimde bırakmak değil? Üretim kodunun şirketi utandırmaması, sabit diski biçimlendirmemesi, veritabanını bozmaması ve cumhurbaşkanını tehdit eden e-postaları göndermemesi gerekiyor. Kısacası, hata ayıklama kodunu bu konuda endişelenmenize gerek kalmayacak güvenli bir yere yazabilmek güzel.


2
Sanırım sorum şu: Neden bu kod yayınlanmadan önce kaldırılmalıdır? Kontroller çok bir performans kaybı değildir ve başarısız olursa kesinlikle daha doğrudan bir hata mesajı tercih ediyorum bir sorun var. Bir iddia yerine istisna kullanmak bana ne avantaj sağlar? Muhtemelen ilgisiz kodun bunu yapabilmesini catch(...)istemezdim.
Kimse

2
@Hiç kimse İddia olmayan ihtiyaçlar için iddiaları kullanmamanın en büyük avantajı okuyucularınızı şaşırtmamaktır. Kodun devre dışı bırakılmasını istemiyorsanız, kodun olacağını bildiren deyimleri kullanmayın. if (DEBUG)Kod hata ayıklama dışında bir şeyi kontrol etmek için kullanmak kadar kötü . Mikro optimizasyon sizin durumunuzda hiçbir şey ifade etmeyebilir. Ancak deyim, sadece ihtiyacınız olmadığı için yıkılmamalıdır.
candied_orange

Sanırım niyetimi yeterince netleştirmedim. Belirli bir uygulamadan assertdeğil, bir iddia kavramından bahsediyorum . assertOkuyucuları kötüye kullanmak ya da karıştırmak istemiyorum . İlk etapta neden böyle olduğunu sormak istedim. Neden ek yok release_assert? Buna gerek yok mu? Serbest bırakılmada iddia edilen engellemenin ardındaki mantık nedir?
Kimse

2
You're asking for a good abstraction.Bundan emin değilim. Çoğunlukla iyileşmenin olmadığı ve asla olmaması gereken sorunlarla uğraşmak istiyorum. Bunu birlikte götürün Because production code needs to [...] not format the hard drive [...]ve değişmezlerin kırıldığı durumlar için her zaman UB'nin serbest bırakılmasında bir iddia alacağımı söyleyebilirim.
Kimse

1
@ Hiç kimse "iyileşme olmayan sorunlar" istisnalar atılarak ve yakalanmadan çözülemez. Bunların hiçbir zaman istisnanın mesaj metninde olmaması gerektiğini not edebilirsiniz.
candied_orange

4

İddialar bir savunma programlama tekniği değil bir hata ayıklama aracıdır . Her koşulda doğrulama yapmak istiyorsanız, koşullu yazarak doğrulama yapın veya ısıtıcı plakayı azaltmak için kendi makronuzu oluşturun.


4

assertyorumlar gibi bir belge türüdür. Yorumlar gibi, bunları normalde müşterilere göndermezsiniz - onlar sürüm koduna ait değildir.

Ancak yorumlarla ilgili sorun, güncelliğini yitirebilmeleridir ve yine de içeri girerler. Bu nedenle, iddialar iyidir - hata ayıklama modunda kontrol edilirler. İddia eskimiş olduğunda, çabucak keşfedersiniz ve yine de iddiayı nasıl düzelteceğinizi bileceksiniz. 3 yıl önce modası geçmiş olan bu yorum? Kimse tahmin edebilir.


1
Peki, bir şey kötüleşmeden önce başarısız bir değişkeni iptal etmek geçerli bir kullanım örneği değil mi?
Kimse

3

Bir "iddia" nın kapatılmasını istemiyorsanız, benzer bir etkiye sahip basit bir işlev yazmaktan çekinmeyin:

void fail_if(bool b) {if(!b) std::abort();}

Olduğunu, assertsen testler içindir yapmak onları sevk üründe uzağa gitmek istiyorum. Bu testin programın tanımlı davranışının bir parçası olmasını istiyorsanız assert, yanlış araçtır.


1
Bunun farkındayım. Soru, varsayılanın neden olduğu gibi olduğundan daha fazla.
Kimse

3

İddiaların ne yapması gerektiğini tartışmak anlamsız, yaptığı şeyi yapar. Farklı bir şey istiyorsanız, kendi işlevinizi yazın. Örneğin, hata ayıklayıcıda durur ya da hiçbir şey yapmaz Assert var, ben uygulamayı çökertecek AssertFatal var, hem iddia ve durum işleyebilir sonuç ve iddia bool fonksiyonları Asserted ve AssertionFailed var.

Beklenmedik bir sorun için hem geliştirici hem de kullanıcı tarafından en iyi çözümün hangisi olduğuna karar vermeniz gerekir.


Niyetimin ne yapması gerektiğini tartışmak niyetim değildi. Bu soru için motivasyonum, sürüm yapısında bulunmadığı iddialarının ardındaki mantığı bulmaktı, çünkü kendim yazmak üzereyim ve kullanım durumları, beklentiler ve tuzaklar hakkında bilgi toplamak istiyorum.
Kimse

Hımm, verify(cond)sonucu ileri sürmenin ve döndürmenin normal yolu olmaz mıydı ?
Deduplicator

1
Ben C değil Ruby kodlama, ama yukarıdaki cevapların çoğuna katılmıyorum, çünkü bir backtrace baskı ile programı durdurmak benim için bir savunma programlama tekniği olarak iyi çalışıyor ....... benim yorum uygun değildi karakterlerde maksimum yorum boyutu bu yüzden aşağıda başka bir cevap yazdım.
Nakilon

2

Diğerlerinin de işaret ettiği gibi, assertprogramcı hatalarına karşı asla gerçekleşmemesi gereken son savunma tablonuzdur. Bunlar, gemi gönderene kadar sağa ve sola başarısız olmamasını sağlayan sağlık kontrolleridir.

Ayrıca , geliştiricilerin yararlı bulabilecekleri her ne nedenle olursa olsun: estetik, performans, istedikleri her şey istikrarlı sürüm yapılarından çıkarılacak şekilde tasarlanmıştır . Bir hata ayıklama derlemesini bir sürüm derlemesinden ayıran şeyin bir parçasıdır ve tanım gereği bir sürüm derlemesi bu tür iddialardan yoksundur. Dolayısıyla , bir önişlemci tanımı olan ve tanımlanmamış bir sürüm oluşturmaya yönelik bir girişim olacak olan analog "yerinde onaylarla sürüm yayınını" serbest bırakmak istiyorsanız tasarımın bir alt _DEBUGdalması vardır NDEBUG; artık gerçek bir sürüm değil.

Tasarım, standart kütüphaneye bile uzanır. Sayısız arasında çok temel bir örnek olarak, uygulamalarında bir çok std::vector::operator[]olacak assertbir aklı kontrol Eğer sınırların dışında vektör kontrol etmiyor emin olmak. Ve bir sürüm derlemesinde bu tür kontrolleri etkinleştirirseniz standart kütüphane çok, çok daha kötü performans göstermeye başlayacaktır. Karşılaştırmasıvector kullanılarakoperator[]ve eski düz bir dinamik diziye karşı dahil edilen bu tür iddialara sahip bir doldurma ctoru, siz bu tür kontrolleri devre dışı bırakana kadar dinamik dizinin genellikle çok daha hızlı olduğunu gösterir, bu nedenle performansı çok önemsiz yollardan çok uzakta yaparlar. Burada boş bir işaretçi denetimi ve sınır dışı bir denetim, bu tür denetimler, akıllı bir işaretçiyi silmek veya bir diziye erişmek kadar basit olan koddan önceki kritik döngülerdeki her kareye milyonlarca kez uygulanıyorsa, büyük bir masraf haline gelebilir.

Bu nedenle, büyük olasılıkla iş için farklı bir araç ve kilit alanlarda bu tür sağlık kontrolleri yapan sürüm derlemelerinden çıkarılmak üzere tasarlanmamış bir araç istiyorsunuz. Kişisel olarak bulduğum en faydalı günlük kaydı. Bu durumda, kullanıcı bir hata rapor ettiğinde, bir günlük eklerse işler çok daha kolay hale gelir ve günlüğün son satırı, hatanın nerede oluştuğu ve ne olabileceği konusunda bana büyük bir ipucu verir. Daha sonra, hata ayıklama derlemesinde adımlarını yeniden oluşturduktan sonra, bir onaylama hatası alabilirim ve bu onaylama hatası bana zamanımı düzene koymak için büyük ipuçları veriyor. Günlüğe kaydetme nispeten pahalı olduğundan, genel bir veri yapısında bir dizinin sınırlardan erişilemediğinden emin olmak gibi son derece düşük düzeyli sağlık kontrolleri uygulamak için kullanmıyorum.

Yine de son olarak ve sizinle biraz anlaşarak, alfa testi sırasında test cihazlarına bir hata ayıklama derlemesine benzeyen bir şey vermek isteyebileceğiniz makul bir durum görebilirim, örneğin, bir NDA imzalayan küçük bir alfa test grubuyla . Test cihazlarınızı, çalıştırdıkları testler ve yazılımı çalıştırırken daha ayrıntılı çıktı gibi bazı hata ayıklama / geliştirme özellikleriyle birlikte bazı hata ayıklama bilgileriyle birlikte tam sürüm derlemesinden başka bir şey verirseniz, alfa testini düzene sokabilir. En azından alfa için böyle şeyler yapan büyük oyun şirketleri gördüm. Ancak bu, test kullanıcılarına gerçekten bir sürüm derlemesi dışında bir şey vermeye çalıştığınız alfa veya dahili test gibi bir şey içindir. Aslında bir sürüm derlemesi göndermeye çalışıyorsanız, tanım gereği,_DEBUG "debug" ve "release" derlemeleri arasındaki farkı gerçekten karıştıran başka bir şey.

Bu kod yayınlanmadan önce neden kaldırılmalıdır? Kontroller çok bir performans kaybı değildir ve başarısız olursa kesinlikle daha doğrudan bir hata mesajı tercih ediyorum bir sorun var.

Yukarıda belirtildiği gibi, kontroller performans açısından önemsiz olmak zorunda değildir. Birçoğu muhtemelen önemsizdir, ancak yine de standart lib bunları kullanıyor ve std::vectoroptimize edilmiş bir sürüm derlemesi olarak 4 kat daha uzun sürdüğü takdirde, birçok durumda performansı kabul edilemez bir şekilde etkileyebilir. çünkü asla başarısız olması gerekmeyen kontrolleri.

Eski bir ekipte, aslında hata ayıklama yapılarının daha hızlı çalışmasını sağlamak için matris ve vektör kütüphanemizin bazı kritik yolları bazı eklemeleri hariç tutması gerekiyordu, çünkü bu varsayımlar matematik işlemlerini olduğu noktaya kadar büyük ölçüde yavaşlatıyordu. ilgi kodunu bile izleyebilmemiz için 15 dakika beklememizi gerektiriyordu. Meslektaşlarım aslındaassertsçünkü bunu yapmanın büyük bir fark yarattığını fark ettiler. Bunun yerine, kritik hata ayıklama yollarından kaçınmaya karar verdik. Bu kritik yolları sınır kontrolünden geçmeden doğrudan vektör / matris verilerini kullandığımızda, tam işlemi gerçekleştirmek için gereken süre (sadece vektör / matris matematiğinden fazlasını içeren) dakikalardan saniyelere indirildi. Bu aşırı bir durum ama kesinlikle varsayımlar performans açısından her zaman ihmal edilemez, hatta yakın bile değil.

Ama aynı zamanda bu şekilde assertstasarlandı. Tahtada bu kadar büyük bir performans etkisi olmadıysa, bir hata ayıklama oluşturma özelliğinden daha fazlası olarak tasarlandıysa ya da vector::atsürüm oluşturmalarında bile sınırların kontrol edilmesini ve sınırların dışına çıkmasını içeren bunları kullanabiliriz erişim (ör. büyük bir performans isabeti ile). Ancak şu anda, durumlarımdaki büyük performans etkileri göz önüne alındığında, tasarımları çok daha yararlı buluyorum NDEBUG, tanımlandığında sadece atlanan bir hata ayıklama-oluştur özelliği . En azından birlikte çalıştığım vakalar için, ilk etapta asla başarısız olmaması gereken akıl sağlığı kontrollerini dışlamak, bir sürüm derlemesi için büyük bir fark yaratıyor.

vector::at vs. vector::operator[]

Bu iki yöntemin ayrımı, bunun yanı sıra alternatifin de merkezinde yer alıyor: istisnalar. vector::operator[]tipik assertolarak sınırların dışında erişimin bir sınırın dışında bir vektöre erişmeye çalışırken kolayca tekrarlanabilir bir hatayı tetikleyeceğinden emin olmak için kullanılır. Ancak kütüphane uygulayıcıları bunu, optimize edilmiş bir sürüm derlemesinde bir kuruşa mal olmayacağı varsayımıyla yapıyorlar.

Bu arada vector::ather zaman sınırları kontrol durumlar o yapar ve serbest bırakma oluşturur bile atar temin ama sık sık çok daha kod kullanarak bkz noktasına buna bir performans kaybına sahiptir vector::operator[]daha vector::at. C ++ tasarımının birçoğu "kullandığınız / ihtiyaç duyduğunuz şey için ödeme yapın" fikrini yansıtır ve birçok insan genellikle, tercih operator[]ettikleri fikrine dayanarak, sürüm yapılarını kontrol eden sınırlarla bile uğraşmaz. Optimize edilmiş sürüm yapılarında sınırların kontrol edilmesi gerekmez. Aniden sürüm derlemelerinde iddialar etkinleştirilirse, bu ikisinin performansı aynı olur ve vektör kullanımı her zaman dinamik bir diziden daha yavaş olur. Dolayısıyla, iddiaların tasarımının ve faydasının büyük bir kısmı, bir sürüm derlemesinde özgür olmaları fikrine dayanmaktadır.

release_assert

Bu niyetleri keşfettikten sonra bu ilginç. Doğal olarak herkesin kullanım durumları farklı olurdu, ama ben release_assertkontrol yapmak ve yayın sürümlerinde bile bir satır numarası ve hata mesajı gösteren yazılım çökecek bazı kullanım bulabilirsiniz düşünüyorum .

Benim durumumda, bir istisna atıldığında olduğu gibi yazılımın zarif bir şekilde iyileşmesini istemediğim bazı belirsiz durumlar için olurdu. Yazılımın hiç gerçekleşmemesi gereken bir şeyle karşılaştığında kullanıcıya rapor vermek için bir satır numarası verilebilmesi için bu durumlarda bile çökmesini istiyorum, yine de harici giriş hataları değil, programcı hataları için akıl kontrolü istisnalar, ancak serbest bırakılma maliyeti hakkında endişelenmeden yapılacak kadar ucuz.

Aslında ben bir sürümde tutmak için yeterince ucuz olabilir atılan bir istisna zarifçe kurtarmak için tercih edilen bir satır numarası ve hata mesajı ile sabit bir çökme bulabilirsiniz bazı durumlar vardır . Ve mevcut bir durumdan kurtarmaya çalışırken karşılaşılan bir hata gibi, bir istisnadan kurtarmanın imkansız olduğu bazı durumlar vardır. Orada release_assert(!"This should never, ever happen! The software failed to fail!");kontrol için ilk etapta olağanüstü bir yol içinde yapılacak ve normal yürütme yollarında hiçbir maliyeti olmayacak çünkü bir ve doğal olarak kir ucuz olurdu mükemmel bir uyum bulur .


Niyetim üçüncü taraf kodundaki ekleri etkinleştirmek değildi, açıklayıcı düzenlemeye bakın. Yorumumdaki alıntı, sorumun bağlamını atlıyor: Additionally, the performance argument for me only counts when it is a measurable problem.Bu nedenle, fikir, ne zaman sürümden bir iddiayı çıkaracağına duruma göre karar vermektir.
Kimse

Son açıklamayla ilgili sorunlardan biri, standart kitaplığın , makroyu kullanırken kullandığınızla assertaynı _DEBUG/NDEBUGönişlemci def'lerine dayanan kütüphaneyi kullanmasıdır assert. Bu nedenle, standart lib için de etkinleştirmeden, örneğin standart lib kullandığını varsayarak, yalnızca bir kod parçası için iddiaları seçici olarak etkinleştirmenin bir yolu yoktur.

Ayrı ayrı devre dışı bırakabileceğiniz STL yineleyici kontrolü vardır, bu da bazı iddiaları devre dışı bırakır, ancak hepsini devre dışı bırakır.

Temelde, tanecikli olmayan kaba bir araçtır ve her zaman bu tasarım sürümünde devre dışı bırakılmak niyetiyle, bu nedenle ekip arkadaşlarınız, sürüm performansını etkilemeyeceği varsayımına karşı kritik alanlarda kullanabilir, standart kütüphane Kritik alanlarda, diğer üçüncü taraf kütüphaneleri bu şekilde kullanırlar, vb assert.

vector::operator[]ve vector::atörneğin, sürüm derlemelerinde onaylamalar etkinleştirildiyse pratik olarak aynı performansa sahip olacaktı ve operator[]yine de sınır denetimini yapacağı için performans açısından artık kullanmanın bir anlamı olmayacaktı.

2

C / C ++ değil, Ruby kodlama ve bu yüzden ekler ve istisnalar arasındaki fark hakkında konuşmayacağım ama çalışma zamanı durduran bir şey olarak bu konuda konuşmak istiyorum . Yukarıdaki yanıtların çoğuna katılmıyorum, çünkü programı bir geri iz yazdırarak durdurmak, benim için bir savunma programlama tekniği olarak işe yarıyor .
Onaylama rutini için bir yol varsa (sözdizimsel olarak nasıl yazılırsa yazılsın ve programlama dilinde veya dsl'de "assert" kelimesi kullanılırsa veya mevcutsa), bu, bazı işlerin yapılması ve ürünün derhal "kullanıma hazır, kullanıma hazır" durumundan "yama gereksinimine" geri döner - şimdi ya gerçek istisna işlemesine yeniden yazabilir ya da yanlış verilerin görünmesine neden olan bir hatayı düzeltebilirsiniz.

Yani Assert, sık yaşamanız ve sık aramanız gereken bir şey değil - bir daha asla gerçekleşmemesi için bir şey yapmalısınız. Ve "sürüm derlemesinin iddialara sahip olmaması gerekir" demek, "sürüm derlemesinin hatalara sahip olmaması gerekir" demek gibidir - ahbap, neredeyse imkansız, onunla başa çıkmak.
Veya "son kullanıcı tarafından yapılan ve yürütülen başarısız test testleri" olarak düşünün. Kullanıcının programınızla yapacağı her şeyi tahmin edemezsiniz, ancak eğer çok ciddi bir şey yanlış giderse, durmalıdır - bu, inşa boru hatlarını nasıl inşa ettiğinizle benzerdir - süreci durdurur ve yayınlamazsınız, değil mi? ? İddia, kullanıcıyı durmaya, raporlamaya ve yardımınızı beklemeye zorlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.