Daha sıkı bir dil kullanmak, sadece kale direğini uygulamanın doğru hale getirilmesinden spesifikasyonu doğru hale getirmeye taşımakla kalmaz. Çok yanlış ama mantıksal olarak tutarlı bir şey yapmak zordur; bu yüzden derleyiciler çok fazla hata yakalar.
İşaretçi Aritmetiği normalde formüle edildiği için sağlam değildir, çünkü tip sistemi aslında ne anlama geldiği anlamına gelmez. Çöp toplanan bir dilde (soyutlama için de ödeme yapmanızı sağlayan normal yaklaşım) çalışarak bu sorunu tamamen önleyebilirsiniz. Veya ne tür işaretçiler kullandığınız konusunda çok daha spesifik olabilirsiniz, böylece derleyici tutarsız olan veya yazıldığı gibi doğrulanamayan herhangi bir şeyi reddedebilir. Rust gibi bazı dillerin yaklaşımı budur.
Yapılandırılmış türler provalara eşdeğerdir, bu yüzden bunu unutan bir tür sistemi yazarsanız, her şey ters gider. Bir süre için bir tür beyan ettiğimizde, aslında değişkente ne olduğu hakkında gerçeği iddia ettiğimizi varsayalım.
- int * x; // Yanlış bir iddia. x var ve bir int'i göstermiyor
- int * y = z; // Yalnızca z'nin bir int'i gösterdiği kanıtlanırsa doğrudur
- * (x + 3) = 5; // Yalnızca (x + 3) x ile aynı dizideki bir int'i gösteriyorsa doğrudur
- int c = a / b; // Yalnızca b sıfırdan farklı olduğunda doğrudur, örneğin: "nonzero int b = ...;"
- sıfırlanabilir int * z = NULL; // nullable int *, int * ile aynı değildir
- int d = * z; // Yanlış bir iddia, çünkü z boş bırakılabilir
- eğer (z! = NULL) {int * e = z; } // Tamam çünkü z boş değil
- serbest (y); int w = * y; // Yanlış iddia, çünkü y artık w'de yok
Bu dünyada işaretçiler boş olamaz. NullPointer dereferences mevcut değildir ve işaretçilerin hiçbir yerde boş olup olmadıklarını kontrol etmeleri gerekmez. Bunun yerine "nullable int *", değeri null veya bir işaretçiye çıkarılabilen farklı bir türdür. Bu, null olmayan varsayımın başladığı noktada , istisnanızı günlüğe kaydedeceğiniz veya null bir dalı geçireceğiniz anlamına gelir.
Bu dünyada, sınırların dışında dizi hataları da mevcut değildir. Derleyici sınırda olduğunu kanıtlayamazsa, derleyicinin bunu kanıtlayabilmesi için yeniden yazmaya çalışın. Eğer yapamazsa, o noktaya manuel olarak bir Varsayım koymanız gerekir; derleyici daha sonra bir çelişki bulabilir.
Ayrıca, başlatılmamış bir işaretçiniz yoksa, başlatılmamış belleğe yönelik işaretçileriniz olmaz. Belleği boşaltmak için bir işaretçiniz varsa, derleyici tarafından reddedilmelidir. Rust'ta, bu tür kanıtları beklemeyi makul kılmak için farklı işaretçi türleri vardır. Sadece sahip olunan işaretçiler (diğer ad yok), derin değişmez yapılara işaretçiler vardır. Varsayılan depolama türü değiştirilemez vb.
Girdi yüzey alanını tam olarak tahmin edilenle sınırlamak için protokoller (arayüz üyeleri içeren) üzerinde iyi tanımlanmış gerçek bir gramer uygulanması da vardır. "Doğruluk" ile ilgili olan şey: 1) Tüm tanımlanmamış durumlardan kurtulun 2) Mantıksal tutarlılığı sağlayın . Oraya ulaşmanın zorluğu, son derece kötü aletler kullanmakla (doğruluk açısından) çok şey ifade ediyor.
Bu yüzden en kötü iki uygulama küresel değişkenler ve gotolardır. Bu şeyler, her şeyin önüne / post / değişmez koşullarının konulmasını engeller. Ayrıca türlerin bu kadar etkili olmasının nedeni de budur. Türler güçlendikçe (nihayetinde gerçek değeri hesaba katmak için Bağımlı Türleri kullanarak), kendi içinde yapıcı doğruluk kanıtı olmaya yaklaşırlar; tutarsız programlar yapmak derleme başarısız.
Bunun sadece aptalca hatalarla ilgili olmadığını unutmayın. Ayrıca, kod tabanını akıllı sızıntılardan korumakla da ilgilidir. "Resmi olarak belirtilen protokolü izler" gibi önemli özelliklerin inandırıcı bir makine tarafından üretilen kanıtı olmadan bir sunumu reddetmeniz gereken durumlar olacaktır.