C ++ Çekirdek Kuralları ES.20 kuralına sahiptir: Her zaman bir nesneyi başlat .
Kullanılan önceden ayarlanmış hatalardan ve bunların tanımsız davranışlarından kaçının. Karmaşık başlatmanın anlaşılmasıyla ilgili sorunlardan kaçının. Yeniden düzenlemeyi basitleştirin.
Fakat bu kural böcek bulmaya yardımcı olmaz, sadece onları gizler.
Bir programın başlatılmamış bir değişken kullandığı bir yürütme yoluna sahip olduğunu varsayalım. Bu bir hatadır. Tanımlanmamış davranış bir yana, bu aynı zamanda bir şeyin yanlış gittiği anlamına geliyor ve program muhtemelen ürün gereksinimlerini karşılamıyor. Üretime dağıtılacağı zaman, bir para kaybı olabilir, hatta daha da kötüsü olabilir.
Hataları nasıl tararız? Testler yazıyoruz. Ancak, testler yürütme yollarının% 100'ünü kapsamaz ve testler program girişlerinin% 100'ünü asla kapsamaz. Bundan daha fazlası, bir test bile hatalı bir uygulama yolunu kapsıyor - yine de geçebiliyor. Sonuçta tanımsız davranış, başlatılmamış bir değişkenin biraz geçerli bir değeri olabilir.
Ancak testlerimize ek olarak, başlatılmamış değişkenlere 0xCDCDCDCD gibi bir şey yazabilen derleyicilerimiz var. Bu, testlerin tespit oranını biraz artırır.
Daha da iyisi - başlatılmamış bellek baytlarının tüm okurlarını yakalayacak Adres Sanitizer gibi araçlar var.
Ve son olarak, programa bakıp bu yürütme yolunda önceden ayarlanmış bir okuma olduğunu söyleyebilecek statik analizörler var.
Bu yüzden birçok güçlü aracımız var, ancak değişkeni başlatırsak - sterilizatörler hiçbir şey bulamazlar .
int bytes_read = 0;
my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*);
// bytes_read is not changed on read error.
// It's a bug of "my_read", but detection is suppressed by initialization.
buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here.
// Another bug: use empty buffer after read error.
use(buffer);
Başka bir kural var - program yürütme bir hatayla karşılaşırsa, program en kısa sürede ölmelidir. Onu hayatta tutmaya gerek yok, sadece kaza, kaza dökümü yazma, mühendislere soruşturması için verme.
Değişkenleri sıfırlamak gereksiz yere tersi yapar - aksi halde zaten bir segmentasyon hatası alacağı zaman, program canlı tutulur.
\0
buggy. Bununla ilgilenmemesi belgelenirse, arama kodunuz buggy'dir. Kullanmadan bytes_read==0
önce arama yapmak için arama kodunu düzeltirseniz, başladığınız yere geri dönersiniz: başlatmazsanız kodunuz buggy, eğer yaparsanız bytes_read
güvenlidir. ( Genelde fonksiyonların bir hata durumunda bile parametrelerini doldurması gerekir : tam olarak değil. Oldukça sık sık çıktılar yalnız bırakılmış veya tanımsız kalmıştır.)
err_t
döndürdüğü görmezden gelmesinin bir nedeni var mı my_read()
? Örnekte herhangi bir yerde bir böcek varsa, o kadar.
bytes_read
değişmediyse (bu yüzden sıfır tutulursa), bunun neden bir hata olması gerekiyor? Program, dolaylı olarak beklenmediği sürece, aklı başında bir şekilde devam edebilirbytes_read!=0
. Bu yüzden dezenfektanlar şikayetçi değil. Öte yandan, ne zamanbytes_read
önceden başlatılmadı, program böylece başlatılıyor değil, aklı başında bir şekilde devam etmek mümkün olmayacaktırbytes_read
aslında tanıtır önceden yoktu bir hata.