- Video ini menjelaskan mengapa perangkat lunak jet tempur dan roket, di mana bug satu baris bisa berujung fatal pada kecepatan Mach 1, menghapus sebagian besar fitur C++ dan hanya menyisakan kode yang dapat diprediksi
- Merangkum sejarah bagaimana komputer pemboman mekanis F-4, mikroprosesor rahasia F-14, serta perang bahasa militer yang berlanjut dari Jovial·CMS-2·Ada dan ledakan jumlah kode akhirnya menuntut satu bahasa aman dan standar yang ketat
- Menunjukkan dengan kode nyata bagaimana standar JSF C++ yang dibuat Lockheed saat meyakinkan penggunaan C++ alih-alih Ada dalam pengembangan F-35 melarang exception, rekursi, dan alokasi memori dinamis, lalu menggantinya dengan kode pengembalian, loop iteratif, dan reservasi memori di awal
- Bersamaan dengan fakta bahwa komputer misi F-35 generasi awal menggunakan arsitektur keluarga PowerPC, video ini menghubungkan X-Plane 12 dan MFD buatan sendiri untuk membandingkan bagaimana kode yang melanggar aturan JSF dan kode yang mematuhinya benar-benar berbeda saat penerbangan berlangsung
- Menyimpulkan bahwa standar JSF kemudian mengarah pada standar keselamatan seperti NASA F-Prime·MISRA·AutoSAR, dan bahwa di atas warisan itu, arah yang lebih tepat saat ini adalah menggunakan C++ Core Guidelines dan C++ modern
Perkenalan pembicara
- Seorang pengembang yang pernah menulis kode C++ untuk sistem kedirgantaraan dan melakukan demo untuk Angkatan Udara
- Penjelasan disampaikan berdasarkan pengalaman nyata menggunakan C++ pada sistem dengan tuntutan keselamatan yang tinggi
- Menggunakan MFD (multifunction display) buatan sendiri yang terdiri dari X-Plane 12, web API, UI Python, dan backend C++ sebagai lingkungan demo
Perangkat lunak penerbangan dan lingkungan yang tidak mentoleransi kegagalan
- Pada aplikasi umum, crash biasanya selesai dengan restart, tetapi pada jet tempur Mach 1 dan roket, satu kali kegagalan langsung berarti bencana
- Kalimat “di Mach 1 tidak ada waktu untuk menunggu garbage collector” menekankan kebutuhan real-time
- Dalam situasi di mana satu baris kode yang salah dapat berujung fatal, pemilihan fitur bahasa itu sendiri harus menjadi mekanisme keselamatan
- Insiden ledakan Ariane 5 pada 1996 diajukan sebagai contoh utama
- Exception terjadi saat nilai floating-point 64-bit horizontal bias dikonversi menjadi integer 16-bit, dan exception ini tidak tertangani
- Bahasa memang memunculkan error sesuai spesifikasi, tetapi sistem gagal menanganinya sehingga roket senilai 500 juta dolar langsung hancur
- Dengan kasus ini sebagai titik acuan, tim perancang F-35 memilih pendekatan memangkas fitur bahasa itu sendiri agar kesalahan yang sama tidak terulang
Sejarah perangkat lunak militer dan perang bahasa
- Pada era jet tempur awal seperti F-4 Phantom, praktis belum ada perangkat lunak
- Komputer pembomannya lebih mirip perangkat mekanis presisi yang terdiri dari roda gigi dan cam, dan “kode”-nya adalah bentuk cam logam itu sendiri
- Situasi berubah pada proyek rahasia pesawat superioritas udara Angkatan Laut, VFX (F-14 Tomcat)
- Belakangan terungkap bahwa Garrett AiResearch merancang mikroprosesor untuk F-14 bahkan sebelum Intel 4004 yang di buku pelajaran dikenal sebagai “mikroprosesor pertama”
- Untuk mengendalikan optimal sayap ayun (swing wing) F-14 diperlukan mikroprosesor berperforma tinggi, dan di dalamnya dimuat sekitar 2.500 baris microcode untuk menghitung polinomial
- Setelah itu, tiap matra mengadopsi bahasa berbeda sehingga dimulailah fragmentasi bahasa
- Angkatan Udara menggunakan Jovial (Jules Own Version of the International Algorithmic Language) yang berada di keluarga ALGOL
- Angkatan Laut, enggan memakai bahasa Angkatan Udara, memilih CMS-2 untuk F-18
- Karena bahasa dan arsitektur hardware berbeda-beda, reuse kode dan verifikasi menjadi hampir mustahil
- Pada saat yang sama, ukuran perangkat lunak per pesawat bertambah secara eksponensial
- Disebutkan contoh angka: F-16A sekitar 125 ribu baris, B-1 sekitar 1 juta baris, dan F-35 modern sekitar 9 juta baris
- Survei Departemen Pertahanan melaporkan bahwa lebih dari 450 bahasa pemrograman sedang digunakan, dan hampir tidak ada yang memiliki standar yang layak
Pemberlakuan Ada dan keterbatasannya
- Untuk mengatasi kekacauan ini, Departemen Pertahanan membuat satu bahasa tingkat tinggi tunggal, Ada, dan mewajibkan penggunaannya dengan sangat ketat
- Jika proyek baru ingin tidak memakai Ada, mereka harus membuktikan mengapa hal itu tidak mungkin dilakukan dengan Ada; jika tidak, kontrak tidak akan didapat
- Ada diperkenalkan sebagai bahasa yang sangat cocok untuk bidang yang menuntut keselamatan dan keandalan
- Ditekankan bahwa desainnya ditujukan untuk menjamin keamanan memori dan tipe pada sistem safety-critical seperti kedirgantaraan
- Namun memasuki 1990-an, mulai tampak jarak dengan realitas industri
- Di sisi lain, internet, Windows 95, dan game komersial berbasis C++ menjadi arus utama
- Mahasiswa dan pengembang secara alami beralih ke GCC gratis dan C++, bukan compiler Ada yang mahal
- Compiler Ada berharga ribuan dolar dan sulit diakses individu, sehingga jumlah tenaga ahli Ada pun ikut menyusut
F-35 dan lahirnya standar JSF C++
- F-35 (Joint Strike Fighter) sejak awal dirancang sebagai pesawat dengan porsi perangkat lunak yang sangat besar
- Perhitungan kompleks seperti sensor fusion menjadi inti pengoperasian pesawat
- Lockheed Martin mengusulkan kepada Departemen Pertahanan agar penggunaan C++ diizinkan untuk memenuhi kebutuhan tersebut
- Ini pada dasarnya adalah permintaan untuk “melonggarkan” kebijakan wajib Ada, dan untuk meyakinkannya diperlukan cara mengendalikan risiko C++
- Disebutkan pula bahwa pencipta C++, Bjarne Stroustrup, ikut terlibat sebagai penasihat dalam perancangan aturan JSF C++
- Ia mengatakan terlibat langsung membantu penyusunan aturan JSF, dan karena itu mengakui sendiri bahwa ia mungkin memiliki bias terhadap standar tersebut
- Gagasan intinya mirip dengan tag “remove before flight”
- Seperti tag yang harus dilepas sebelum terbang, fitur-fitur C++ yang berbahaya dihapus pada level bahasa sehingga hanya subset yang dapat diprediksi yang digunakan
- Dengan begitu, keselamatan setingkat Ada bisa dicapai sambil tetap memanfaatkan sebagian daya ekspresif C++
Hardware nyata dan analogi GameCube
- Blok awal F-35 menggunakan komputer misi berbasis prosesor Motorola G4 PowerPC
- Informasi ini dipublikasikan antara lain dalam artikel Aviation Today tahun 2003
- Karena GameCube juga menggunakan prosesor keluarga PowerPC, analogi ini menarik sebagai hardware generasi serupa pada level instruction set
- Untuk kecocokan generasi yang lebih presisi mungkin ada konsol lain yang lebih dekat, tetapi analogi GameCube sudah cukup untuk memahami prinsipnya
Lingkungan demo JSF C++: X-Plane 12 + MFD
- Berdasarkan X-Plane 12, pembicara membangun lingkungan simulator penerbangan menggunakan addon F-35B dari AOA Simulations
- Dengan web API baru X-Plane, data penerbangan real-time disubscribe lalu ditampilkan pada MFD
- Frontend disusun dengan Python, sedangkan backend ditulis sebagai plugin C++, untuk mendemonstrasikan perbandingan kode yang mematuhi dan melanggar aturan JSF
- Berbagai informasi seperti ketinggian, kecepatan, angin, envelope penerbangan, dan data navigasi ditampilkan dari hasil perhitungan C++
- Saat terbang, pembicara sengaja menjalankan kode C++ non-standar yang melempar exception sehingga MFD mati dan timbul masalah penerbangan, lalu menunjukkan langkah demi langkah bagaimana aturan JSF menyelesaikan masalah itu
Tiga pembatasan inti JSF: exception, rekursi, memori dinamis
- Tiga pembatasan inti yang ditekankan dalam standar JSF C++ adalah exception, rekursi, dan alokasi memori dinamis
- Selain itu, standar juga menetapkan batas atas Cyclomatic Complexity fungsi
1) Larangan exception – AV Rule 208
- JSF AV Rule 208: “exceptions shall not be used”
- Semua keyword terkait exception seperti try, catch, dan throw dilarang sepenuhnya
- Alasan utamanya adalah ketidakdeterministikan alur kontrol
- Seperti pada Ariane 5, ketika exception terjadi, jika penanganannya terlewat atau timing-nya meleset, seluruh sistem bisa runtuh secara tak terduga
- Bjarne memang berpandangan positif terhadap penanganan exception di C++ modern, tetapi ia menjelaskan bahwa saat JSF dirancang, kematangan tool dan jaminan real-time belum memungkinkan dukungan exception
“JSF++ ditujukan untuk aplikasi hard real-time dan safety-critical (kendali penerbangan), jadi jika komputasi terlalu lama orang bisa mati, dan dengan exception kita tidak bisa menjamin waktu respons”
- Dalam JSF, exception digantikan dengan return code
- Pada contoh perhitungan density altitude, kode pengembalian berbeda ditetapkan untuk tiap kondisi error dan caller menafsirkannya untuk melakukan penanganan
- Dengan begitu, sekalipun perhitungan gagal atau timeout, seluruh program tidak mati dan sisi pemanggil dapat merepresentasikan “status error” secara aman
2) Larangan rekursi – AV Rule 119
- AV Rule 119 melarang fungsi memanggil dirinya sendiri secara langsung maupun tidak langsung, yaitu rekursi
- Setiap pemanggilan rekursif menambah stack frame baru, dan karena batas kedalaman maksimumnya sulit diketahui, risiko stack overflow meningkat
- Sebagai contoh digunakan koefisien binomial (binomial coefficient) untuk perhitungan bandara alternatif dalam perencanaan penerbangan
- Pada versi non-standar, digunakan implementasi rekursif berbentuk
C(n, k) = C(n-1, k-1) + C(n-1, k) - Masalahnya, kedalaman pemanggilan berubah sesuai input sehingga sulit memprediksi batas penggunaan memori
- Pada versi non-standar, digunakan implementasi rekursif berbentuk
- Pada versi yang patuh JSF, perhitungan yang sama diubah menjadi implementasi iteratif berbasis loop
- Kodenya lebih panjang dan kurang elegan, tetapi memberikan hasil yang sama tanpa memanggil dirinya sendiri
- Ini membuat batas kedalaman pemanggilan fungsi dan penggunaan memori lebih mudah dianalisis secara statis
3) Larangan alokasi memori dinamis – AV Rule 206
- AV Rule 206: setelah inisialisasi, tidak boleh ada alokasi maupun dealokasi memori
- Heap allocation saat runtime seperti
new,delete, maupunnewinternal melalui smart pointer dilarang
- Heap allocation saat runtime seperti
- Alasannya ada dua masalah utama
- Heap allocation memiliki ketidakdeterministikan waktu karena durasi yang dibutuhkan tidak pasti
- Jika heap mengalami fragmentasi, alokasi bisa gagal karena tidak ditemukan blok kontinu besar, meskipun total kapasitas masih tersisa
- Sebagai contoh ditunjukkan kode non-standar yang membuat buffer riwayat IAS (indicated airspeed) untuk perhitungan gust menggunakan
std::unique_ptr+ array dinamis- Bentuk ini melanggar aturan JSF karena mengalokasikan array baru saat runtime
- Pada versi yang patuh JSF digunakan array berukuran tetap dengan ukuran maksimum yang ditentukan sebagai konstanta
- Konstanta seperti
MAX_IAS_HISTORYdidefinisikan, memori dialokasikan sekali saat inisialisasi, lalu hanya indeksnya yang diputar - Dengan begitu, tidak ada alokasi tambahan selama eksekusi sehingga prediktabilitas waktu dan memori dapat dijamin
- Konstanta seperti
4) Batas Cyclomatic Complexity – AV Rule 3
- AV Rule 3 menetapkan bahwa Cyclomatic Complexity fungsi tidak boleh melebihi 20
- Deklarasi fungsi sendiri bernilai 1, lalu if, while, for, switch, logika AND/OR, dan sebagainya masing-masing menambah 1 poin kompleksitas
- Melalui contoh implementasi iteratif koefisien binomial, diperlihatkan bagaimana tiap if, operasi logika, dan loop for meningkatkan poin kompleksitas
- Karena makin tinggi kompleksitas maka pengujian, verifikasi, dan analisis makin sulit, tujuan standarnya adalah menjaganya tetap di bawah batas tertentu
Warisan JSF: NASA F-Prime, MISRA, AutoSAR
- Gagasan standar JSF C++ kemudian menyebar ke bidang safety-critical lain
- Framework perangkat lunak penerbangan NASA, F-Prime, dirilis pada 2017 dan berbagi aturan seperti larangan alokasi memori dinamis, larangan exception, dan larangan rekursi
- Industri otomotif juga mengikuti arus serupa
- Muncul standar seperti MISRA C++ dan AutoSAR (Automotive Open System Architecture) yang menetapkan aturan keselamatan untuk perangkat lunak kendaraan
- Disebutkan bahwa panduan AutoSAR C++14 secara eksplisit merujuk JSF, menunjukkan pengaruh JSF sampai ke perangkat lunak otomotif
- Karena mobil modern pada dasarnya mendekati “komputer beroda”, subset bahasa dan aturan coding seperti ini menjadi fondasi utama keselamatan
Kesimpulan: jika memakai C++ hari ini, apa yang harus diikuti
- Standar JSF C++ dipaparkan sebagai pencapaian rekayasa yang pada masanya berhasil mengecilkan bahasa yang kompleks menjadi subset yang dapat diprediksi demi memperoleh keselamatan setingkat kendali terbang jet tempur
- Pada saat yang sama, Bjarne Stroustrup merekomendasikan agar pengembang masa kini mengikuti C++ Core Guidelines dan C++ modern
- Alasannya, bahasa C++ dan toolchain-nya telah berkembang pesat selama beberapa dekade, sehingga fitur seperti exception dan smart pointer kini dalam banyak kasus bisa digunakan dengan aman
- Meski demikian, JSF tetap menjadi contoh penting dari cara berpikir mengendalikan bahasa bukan dengan menambah, melainkan dengan “menghapus”
- Penutupnya menegaskan bahwa dalam desain sistem safety-critical, yang terpenting bukan hanya apa yang akan dimasukkan, tetapi apa yang harus masuk ke daftar remove before flight
8 komentar
Karena digunakan untuk keperluan militer, saya merasa bisa jadi C++ dipilih sebagai hasil dari upaya menyeimbangkan spesifikasi perangkat keras yang rendah dan fitur-fitur tingkat lanjut.
Mahasiswa dan pengembang tidak mempelajarinya karena itu adalah bahasa yang digunakan oleh kementerian pertahanan dan permintaannya rendah, bukan karena alatnya mahal.
Secara keseluruhan, ini tampaknya membahas teknik menulis kode yang dapat diprediksi.
C++ hanya dijadikan contoh, tetapi bagian-bagian yang menjadi masalah lebih besar dalam bahasa lain, seperti GC, juga pada dasarnya sama, sehingga agak disayangkan karena bisa dipahami seolah-olah sedang membahas keterbatasan C++.
Jika memang tidak akan menggunakan teknik seperti alokasi dinamis atau penanganan pengecualian di C++, saya jadi tetap bertanya-tanya apakah bukankah akan jauh lebih mudah dan cepat menggunakan C lalu menulisnya berdasarkan prinsip-prinsip di atas.
Ya, saya juga tidak paham kenapa harus C++ dan bukan C.
C++ modern memang sangat stabil, tetapi jika memang tidak harus menggunakan C++, rasanya ada baiknya mempertimbangkan bahasa lain yang lebih stabil.
Mari gunakan sintaks RUST dengan STRICT!
Opini Hacker News
Tebalnya 142 halaman, dan kita bisa melihat batasan seperti apa yang ada dalam pengembangan perangkat lunak pesawat sungguhan
Hanya saja saya penasaran dengan pengecualian untuk aturan “shall”. Dalam proyek sebesar ini, kasus pengecualian menunjukkan seberapa efektif standar tersebut
Pada 2005 itu mungkin masuk akal, tetapi saya penasaran bagaimana penerapannya di lingkungan seperti drone berbasis AI saat ini
Bagian seperti larangan
stdio.hterasa asing, tetapi setelah dibaca rasanya jadi “ya, benar juga”a = a;yang pernah saya lihat di kode MISRAItu trik untuk menghindari penghapusan parameter yang tidak digunakan, tetapi saya ragu aturan seperti ini benar-benar menjamin kualitas kode yang baik
Pedoman JSF adalah dokumen tahun 2005, jadi ada keterbatasan zamannya
Menarik juga bahwa Bjarne Stroustrup belakangan ini mengusulkan konsep “profil C++”
Pada akhirnya, panduan gaya seperti ini bisa jadi hanya soal selera estetika
(void)a;Yang benar-benar menjamin keselamatan adalah kualitas desain dan struktur fail-safe
_ = a;Ada juga isu terkait
Justru perannya adalah menyediakan patokan bersama saat melakukan review
Intinya adalah mission assurance
Jika stack atau heap digunakan, alamat memori variabel akan berubah, dan bila sel tertentu rusak maka masalah bisa muncul
Jika semua variabel punya alamat tetap, hanya sel yang rusak itu saja yang bisa dipindahkan lewat patch agar misi tetap berjalan
Variabel lokal, parameter, alamat pengembalian, dan sebagainya pada akhirnya tetap memerlukan stack
Rekursi juga jadi tidak mungkin, dan variabel sementara pun terbatas
Jadi klaim ini tidak realistis
Rentang alamat stack dan heap memang bisa dibuat tetap, tetapi saya ragu itu alasan yang benar-benar meyakinkan
Saya juga biasa meninggalkan log seperti “kasus ini seharusnya tidak pernah terjadi”
Dalam sistem besar, pencatatan situasi pengecualian seperti ini sangat berguna untuk debugging
Semua kasus harus ditangani secara eksplisit, jadi saat nilai enum baru ditambahkan, kompiler akan memberi peringatan
_STOPatau_CRASHuntuk langsung menghentikan debugEfeknya memaksa masalah itu segera diperbaiki
Ringkasnya, alasannya adalah “pengembang Ada dan toolchain-nya kurang”
Namun sekarang keterbukaan terhadap keberagaman bahasa lebih besar, jadi rasanya Ada bisa lebih diterima
Fakta bahwa NVidia mengadopsi SPARK juga terlihat sebagai tanda kebangkitan Ada
Jika DoD mewajibkan Ada, universitas dan perusahaan pasti akan mengikuti
Pada akhirnya bahasa bisa dipelajari, dan jika mereka memakai Ada, keandalan F-35 mungkin juga akan lebih tinggi
Di antaranya AdaCore, GHS, PTC ApexAda, DDC-I, Irvine, OC Systems, dan RR Software
Dulu kompiler Ada adalah opsi berbayar, sedangkan C/C++ disediakan secara default, sehingga sekolah dan perusahaan memilih C++
AdaCore memberi kontribusi besar pada standardisasi ISO dan penyebaran open source
Dulu bahasa ini terlalu sering dikritik, tetapi sekarang justru terasa menarik
Struktur file dan flag build terasa rumit, dan di peringkat bahasa RedMonk pun Ada tidak ada
Beberapa fiturnya memang menarik, tetapi tetap belum memberi pengalaman bahasa modern seperti Rust
Kerangka sertifikasi seperti DO-178C sangat penting
Justru ini mungkin cara yang benar untuk menulis kode dengan keandalan tinggi
Membahas berbagai topik seperti reverse engineering, obfuscation, dan compiler
apakah hal seperti ini memang perlu dituliskan secara eksplisit
Apakah dibuat sendiri oleh LM, atau produk komersial, saya ingin tahu