Bilgisayarınızın başındasınız. Önemli bir iş yetiştiriyorsunuz. Aniden o lanet olası Blue Screen of Death (BSOD) belirdi veya program bir Unhandled Exception (yakalanmamış istisna) fırlattı. Ne yaparsınız? En kötü ihtimalle sinirlenir, sistemi "reboot" edersiniz. Kaybettiğiniz şey sadece birkaç dakika, belki de "save" edilmemiş birkaç satırdır. Peki ya altınızdaki koltuk, ofis sandalyesi değil de sesten hızlı giden bir savaş uçağıysa?
Düşman radarı size kilitlenmiş. Hızınız Mach 1. Tam o sırada yazılımın Runtime Behavior'ında (çalışma zamanı davranışı) küçücük bir sapma oluştu. İşte orada "Ctrl+Alt+Delete" yapma lüksünüz yok.
Havacılıkta bir bug, yarım milyar dolarlık bir varlığın toprağa çakılması, hatta sivil kayıplarla sonuçlanacak bir felaket demektir. Sizin o masum sandığınız yazılım hataları, burada pilotun yaşamı ile ölüm arasındaki o ince çizgidir.
Bu dünyaya Hard Real-Time (Sert Gerçek Zamanlı) sistemler diyorlar. Burada 2 kere 2’nin 4 etmesi yetmez. O sonucun tam gereken milisaniyede üretilmesi gerekir. Sistem bir anlık takılırsa, bellek dolarsa veya bir Garbage Collector devreye girip sistemi dondurursa, sonuç matematiksel olarak doğru olsa bile, pratikte ölüsünüz demektir.
Bugün gökyüzünde süzülen bir F-35, aslında kanat takılmış bir silahtan çok daha fazlasıdır. O, aerodynamic stability'si (aerodinamik kararlılığı) saniyede binlerce kez yazılım tarafından düzeltilen, tabiri caizse "uçan bir veri merkezidir". 9 milyon satırı aşan devasa bir kod yığınından bahsediyoruz.
Peki, insanlık tarihinin en karmaşık mühendislik problemlerinden biri olan bu kaos nasıl yönetiliyor? C++ gibi güçlü ama kontrolsüz bırakıldığında "tehlikeli" olabilen bir dil, nasıl oluyor da bu Safety-Critical (güvenlik kritik) makinelerin beyni haline getiriliyor?
Cevap, kanla yazılmış kurallarda ve "Remove Before Flight" felsefesinde saklı. Gelin, bu sessiz devrimin başladığı yere, dişlilerin döndüğü yıllara gidelim.

Dişlilerden Çiplere Uzanan Dönem
Havacılıkta Software (yazılım) kavramı, bugün bildiğimiz haline gelmeden önce çok farklı bir dünyaydı. Uçağın fiziksel yeteneklerini yöneten yardımcı bir katman değildi; uçağın ta kendisiydi.
Tarih şeridini 1970'lerin başına saralım. O dönemin efsanevi jeti F-4 Phantom'un kokpitindesiniz. Modern anlamda bir yazılım arıyorsunuz ama bulamazsınız. DoD (ABD Savunma Bakanlığı) raporlarına baktığınızda şoke edici bir gerçekle karşılaşırsınız: O dönemdeki atış kontrol ve bombalama bilgisayarları, elektronik devreler değil; dişliler, cams (kamlar) ve mekanik düzeneklerden oluşan, İsviçre saatlerini andıran hassas analog kutulardı.
Yazılımcıların çok sık kullandığı "Hard-coded" terimi var ya? İşte o zamanlar bu terim mecaz değildi, gerçeğin ta kendisiydi. "Kod", metal kamların fiziksel şekli ve dişli oranlarıyla tanımlanıyordu. Bir algoritmayı mı değiştireceksiniz? Klavyeye basamazsınız; o metal parçayı fiziksel olarak söküp yeniden işlemeniz gerekirdi.
Intel Piyasada Yokken O Gizli Çip Vardı
Teknoloji tarihi kitaplarını açın, size dünyanın ilk microprocessor'ü (mikroişlemci) olarak Intel 4004'ü (1971) gösterirler. İnanmayın. Çünkü havacılık tarihi, kamuoyundan uzun süre gizlenen çok daha ileri bir gerçeği saklıyor.
Sahneye F-14 Tomcat çıkıyor. Hani şu meşhur Swing-wing design (değişken geometrili kanat) yapısına sahip canavar. Bu kanatların Mach 2 hızında, yüksek G manevralarında manuel olarak kontrol edilmesi bir pilotun fiziksel kapasitesinin çok ötesindeydi. Bu aerodinamik kaosu yönetmek için Garrett AiResearch firması, Intel'den yıllar önce F-14 için özel bir chipset (yonga seti) geliştirdi. Sistemin adı Central Air Data Computer (CADC) idi.
Bu sistemin kalbinde MP944 yonga seti yatıyordu. F-14'ün uçuş yüzeylerini yöneten karmaşık polinom denklemlerini işleyen bu işlemci, o dönemin Intel 4004'ünden çok daha hızlı ve yetenekliydi.
Peki neden duymadınız?
Çünkü Sovyetler Birliği bu teknolojiyi çalmasın diye sistem 1998 yılına kadar "Top Secret" (Çok Gizli) olarak sınıflandırıldı. Bu sistemde kodlar RAM üzerinde değil, fiziksel olarak ROM'a yakılmış (burned) mikro kodlardan oluşuyordu. F-14, yazılımın uçağın uçuş karakteristiğini doğrudan belirlediği ilk modern platform olarak tarihe geçti. Ancak asıl kaos, yazılımın gücü keşfedilince başlayacaktı.
Savunma Sanayisinin Dil Kargaşası
Erken dönem aviyonik dünyası tam bir Mess (karmaşa) halindeydi . Soğuk Savaş’ın getirdiği o hızlı silahlanma yarışı, her kuvvetin ve her yüklenicinin kendi başının çaresine bakmasına yol açmıştı .
1970'lerin sonuna geldiğimizde ortaya çıkan tablo korkunçtu. Savunma sanayiinde tam 450’den fazla farklı programlama dili kullanılıyordu . Hava Kuvvetleri Jovial diye bir dil tutturmuş gidiyor, Donanma ise bunu reddedip F-18 için kendi dili CMS-2'yi geliştiriyordu .
Bu parçalı yapı stratejik bir kâbus yarattı . Kodların güvenliğini Audit (denetim) etmek imkansızdı çünkü yüzlerce farklı dilde uzmanlaşmış personel bulmak gerekiyordu . Maintenance Costs (bakım maliyetleri) astronomik seviyelere çıkmış, donanım maliyetlerini bile geçmişti . Farklı Komut Seti Mimarileri arasında uyumluluk ise koca bir sıfırdı .
ADA Şartları ve Tek Dil Politikası
ABD Savunma Bakanlığı (DoD) bu gidişata dur demek için masaya yumruğunu vurdu . Radikal bir kararla "Tek Dil" politikasına geçildi: ADA .
Güvenlik kritik (Safety-Critical) uygulamalar için sıfırdan tasarlanan bu dil, teorik olarak mükemmeldi . DoD işi o kadar sıkı tutuyordu ki, bir projede ADA kullanmamak için o işin ADA ile yapılmasının teknik olarak "imkansız" olduğunu kanıtlamanız ve özel bir Waiver (feragat) almanız gerekiyordu . Sektörün kuralı basitti: "ADA kullanmıyorsan kontratı alamazsın" .
Lockheed Martin Tarafından Başlatılan C++ İsyanı
Ancak 90’ların ortasında rüzgar tersine döndü . Sivil dünyada Windows 95, internet devrimi ve oyun endüstrisi patlama yapınca C++ fiili endüstri standardı haline geldi . Üniversite öğrencileri ADA öğrenmeyi bıraktı, yetenekli mühendisler Silikon Vadisi’ne kaçtı . Savunma sanayii yetenek bulamaz hale geldi .
İşte tam bu noktada Lockheed Martin sahneye çıktı. F-35 projesi (o zamanki adıyla Joint Strike Fighter) sadece bir uçak değil, Sensor Fusion (sensör füzyonu) yapan ağ merkezli bir savaş makinesi olacaktı . Bunun için Object-Oriented Programming (Nesne Yönelimli Programlama) esnekliğine ihtiyaçları vardı. DoD’ye gidip o dönem için "densizlik" sayılacak bir teklifte bulundular: "Biz ADA zorlamasını aşmak ve F-35’i C++ ile geliştirmek istiyoruz" .
Bu büyük bir kumardı. Çünkü C++ bellek yönetimi konusunda "güvensiz" doğasıyla bilinirdi . Ancak Lockheed'in bir planı vardı. Dili ham haliyle kullanmayacaklardı. Onu evcilleştirecek, tehlikeli özelliklerini yasaklayacak ve ADA kadar güvenli hale getireceklerdi. Peki bu korku yersiz miydi? Asla. Çünkü tarih, yazılım hatasının ne kadar pahalıya patlayacağını çok acı bir tecrübeyle, Arian 5 kazasıyla yüzlerine vuracaktı.
Yarım Milyar Dolarlık Hata
Yazılım hatalarının maliyetini anlamak için tarihin tozlu sayfalarındaki en pahalı felakete, Ariane 5 kazasına gitmek zorundayız. Tarih 4 Haziran 1996. Avrupa Uzay Ajansı'nın (ESA) gururu, devasa Ariane 5 roketi fırlatma rampasında. Motorlar ateşleniyor, roket yükseliyor. Ancak sadece 37 saniye sonra, 4.000 metre irtifada roket aniden kontrolünü kaybediyor ve kendini imha ediyor. Yarım milyar dolarlık proje, saniyeler içinde gökyüzünde bir havai fişek gösterisine dönüşüyor.
Herkes mekanik bir arıza, bir yakıt sızıntısı veya motor patlaması bekliyordu. Ancak soruşturma raporu açıklandığında dünya şoke oldu. Suçlu ne bir vida ne de bir yakıttı. Suçlu, yazılımın derinliklerinde gizlenen, yakalanmamış bir istisna yani Unhandled Exception idi.
Sorun, roketin Inertial Reference System (Atalet Referans Sistemi - SRI) adı verilen beyninde yaşandı. Yazılım, 64-bitlik bir Floating Point (kayan noktalı sayı) değerini, 16-bitlik bir Signed Integer (işaretli tam sayı) değerine dönüştürmeye çalıştı. Bu değişken, roketin Horizontal Bias (yatay sapma) değeriyle ilgiliydi.
Sorun şuradaydı: Bu kod bloğu, aslında bir önceki nesil olan Ariane 4 roketi için yazılmıştı. Ariane 4 daha yavaştı, uçuş dinamikleri daha sakindi. Onun yatay sapma değeri, matematiksel olarak asla 16-bitlik tamsayı sınırlarını (-32.768 ile +32.767) aşmıyordu. Mühendisler buna o kadar güvenmişti ki, performansı artırmak adına bu spesifik dönüşüm işlemi için Exception Handling (hata yakalama) mekanizmasını bilerek ve isteyerek devre dışı bırakmışlardı.
Ancak Ariane 5, eski versiyonu gibi değildi. Çok daha güçlü ve hızlıydı. Fırlatmanın hemen başında yatay hızı o kadar yüksekti ki, sensörden gelen değer 16-bitlik o daracık kutuya sığmadı.
Sonuç? Arithmetic Overflow (Aritmetik Taşma).
Sistem Operand Error istisnası fırlattı. Ancak mühendisler "burada hata olmaz" diyerek korumayı kapattıkları için, bu istisna yakalanmadı. Sonuç olarak SRI bilgisayarı kendini kapattı. Daha da kötüsü neydi biliyor musunuz? Yedek bilgisayar da (Redundancy) aynı kodu çalıştırdığı için o da aynı milisaniyede çöktü.
Roketin ana uçuş bilgisayarı, kapalı olan SRI sisteminden gelen hata kodlarını (diagnostic data), gerçek uçuş verisi sandı. Roketin motorlarını çılgınca bir açıyla saptırdı. Aerodinamik kuvvetler roketi parçaladı ve sistem kendini imha etti.
F-35 İçin Alınan Ders
İşte bu olay, havacılık yazılımlarında bir milat oldu. Bir dilin sentaks hatası vermemesi, o kodun Runtime Safe (çalışma zamanında güvenli) olduğu anlamına gelmiyordu. Bugün F-35 gibi sistemlerde "Exception" kullanımının yasaklanmasının temelinde, işte bu yarım milyar dolarlık havai fişek gösterisi yatmaktadır.
Kodlama Anayasası ve Uçuştan Önce Elenecekler
F-35 yazılım geliştirme sürecinin temel felsefesi, havacılıkta fiziksel donanımlar için kullanılan o meşhur kırmızı etiketlere dayanır: "Remove Before Flight" (Uçuştan Önce Kaldır).
C++ dili muazzam yeteneklere sahiptir. Ancak bu yeteneklerin bazıları, belirsiz davranışlara (Undefined Behavior) veya zamanlamada sapmalara yol açabilir. Lockheed Martin'in geliştirdiği JSF C++ Coding Standards (AV Kuralları), dili cerrahi bir hassasiyetle budayarak sadece güvenli parçaların kokpite girmesine izin verir.
İşte o yasaklılar listesi ve gerekçeleri.
AV Kuralı 208 ile Gelen İstisna Yasağı Modern yazılım geliştirmede hata yönetiminin temeli olan Exceptions (istisnalar), kesinlikle yasaktır. Kodda try, catch veya throw göremezsiniz.
Neden mi?
Bir istisna fırlatıldığında programın kontrol akışı doğrusal olmaktan çıkar. Çalışma zamanı ortamı (Runtime Environment), bellekte geriye doğru giderek (Stack Unwinding) uygun bir yakalayıcı arar. Bu arama süreci, Hard Real-Time bir sistemde kabul edilemez bir zaman gecikmesine (Latency) neden olabilir.
Bjarne Stroustrup bu kuralın sebebini şöyle açıklar: "Bir hesaplamanın çok uzun sürmesi durumunda birinin ölebileceği gerçeği". Uçuş esnasında hata olursa sistem durmaz, çökmez; önceden tanımlanmış bir hata kodu döndürür ve "bozulmuş modda" (Degraded Mode) uçmaya devam eder.
AV Kuralı 119 ve Özyineleme Yasağı Bilgisayar bilimlerinde Recursion (özyineleme), zarif çözümler sunar. Ancak F-35 kodunda bu kesinlikle yasaktır. Fonksiyonlar asla kendilerini çağıramazlar.
Bunun teknik nedeni Stack Overflow (Yığın Taşması) riskidir. Her fonksiyon çağrısı bellekte yeni bir çerçeve (Stack Frame) oluşturur. Eğer özyineleme derinliği çalışma zamanında kontrolsüzce artarsa bellek tükenir ve uçak düşer.
Güvenlik kritik sistemlerde, yazılımın tüketeceği maksimum bellek miktarının derleme zamanında (Compile-time) kanıtlanabilir olması şarttır. Bu yüzden özyineleme yerine, her zaman maksimum tekrar sayısı belli olan döngüler (Loops) kullanılır. Kod belki daha az "şık" görünür ama asla taşmaz.
AV Kuralı 206 ile Dinamik Bellek Yasağı Belki de modern yazılımcıları en çok şaşırtacak kural budur. Sistem başlatıldıktan sonra Dynamic Memory Allocation (dinamik bellek tahsisi) tamamen yasaktır.
Yani uçağın motorları çalışıp sistem "Mission Mode" geçişi yaptıktan sonra malloc, free, new veya delete komutlarını kullanamazsınız.
Sebep? Heap Fragmentation (Yığın Parçalanması). Sürekli bellek alıp vermek, bellekte delikler oluşturur. Acil bir durumda ihtiyaç duyulan blok bulunamayabilir. Ayrıca işletim sisteminin bellek ayırmak için ne kadar süre harcayacağı öngörülemez (Non-deterministic).
Çözüm basittir ama maliyetlidir: İhtiyaç duyulabilecek tüm veri yapıları, en kötü senaryoya (Worst-case) göre sistem açılırken maksimum boyutta peşin olarak tahsis edilir (Pre-allocation).
AV Kuralı 3 ve Basitlik İlkesi Son olarak kodun karmaşıklığına vurulan neşterden bahsedelim. Cyclomatic Complexity (Siklomatik Karmaşıklık) değeri bir fonksiyon için 20'yi geçemez.
Bu, kodun test edilebilirliği ile ilgilidir. Karmaşıklık ne kadar yüksekse, o fonksiyonu %100 test kapsamına (Code Coverage) almak o kadar zordur. Havacılıkta her bir if, else ve case durumunun test edilmesi zorunludur. Kod basit tutulur ki, bir insan tarafından anlaşılabilir ve hatasız olduğu ispatlanabilir olsun.
Kod Hayattır
F-35 için geliştirilen bu JSF C++ Coding Standards (AV Kuralları), sadece bir savaş uçağının kullanım kılavuzu olarak kalmadı; tüm gömülü yazılım endüstrisini kökünden dönüştürdü .
Bugün NASA'nın Mars yüzeyinde uçurduğu Ingenuity helikopterine bakın. Orada kullanılan açık kaynaklı F-Prime uçuş yazılımı çerçevesi, tıpkı F-35 gibi dinamik bellek tahsisini ve istisnaları kesin bir dille yasaklar .
Ya da garajınızdaki yeni nesil otomobile bakın. Modern araçlar artık tekerlekli birer bilgisayara dönüştü. Otomotiv endüstrisinin kutsal kitabı sayılan AUTOSAR (Automotive Open System Architecture), güvenlik standartlarını belirlerken doğrudan JSF kurallarını referans alır . BMW’den Toyota’ya kadar devler, kod güvenliğini sağlamak için bu disiplinden beslenir .
Modern C++ ve Stroustrup'un Bakışı
Elbette C++ yerinde saymadı. Dilin yaratıcısı Bjarne Stroustrup, bugün Modern C++ Core Guidelines ile daha güncel çözümler öneriyor . constexpr gibi derleme zamanı hesaplamaları ve std::array gibi güvenli yapılarla, JSF'in sağlamaya çalıştığı güvenliği daha modern yollarla sunabiliyor .
Ancak değişmeyen tek bir gerçek var. Bu standartlar, "en zeki kodu" veya "en kısa kodu" yazmakla ilgili değildir. Amaç, Mach 1 hızında giderken, düşman radar kilidi altındayken bile asla çökmeyecek, tahmin edilebilir ve kaya gibi sağlam kodu yazmaktır .
Bir havacılık yazılımcısı için en büyük yetenek, koda ne ekleyeceğini bilmek değil; güvenlik için neyi koddan çıkaracağını, yani "Remove Before Flight" ilkesini bilmektir . Savunma sanayisinde yazılımın başarısı, yazılımın sanat olmaktan çıkıp, askeri bir disiplinle buluştuğu noktada gizlidir .