36 poin oleh GN⁺ 2025-02-17 | 6 komentar | Bagikan ke WhatsApp
  • Analisis kritis terhadap 10 aturan pengembangan perangkat lunak NASA
    • Aturan-aturan ini ditujukan untuk sistem embedded yang sangat kritis (misalnya perangkat lunak wahana antariksa)
    • Namun, perlu dibahas apakah aturan-aturan ini juga tepat untuk lingkungan pengembangan lain, atau dapat diterapkan pada bahasa lain (bukan C)

1. Pertahankan alur kontrol yang sederhana (larangan goto, setjmp/longjmp, rekursi)

  • Aturan ini melarang penanganan pengecualian (setjmp()/longjmp()) dan rekursi.
  • Rekursi tidak selalu tidak efisien. Dengan metode yang tepat, rekursi juga dapat dijamin berhenti.
  • Memaksa rekursi diubah menjadi loop berisiko menghasilkan kode yang sulit dirawat.

Kritik:

  • Jaminan terminasi memang penting, tetapi pembatasan yang ekstrem dapat menghambat keterbacaan dan pemeliharaan.
  • Larangan rekursi tanpa pengecualian sangat mungkin menimbulkan kompleksitas yang tidak perlu.

2. Semua loop harus memiliki batas atas yang jelas

  • Compiler harus dapat menganalisis secara statis jumlah iterasi loop.
  • Namun, hanya dengan menetapkan batas atas tidak berarti waktu eksekusi nyata dapat dijamin.
  • Membatasi kedalaman rekursi bisa sama amannya dengan memberi batas atas pada loop.

Kritik:

  • Sekadar memberi batas atas tidak menjamin waktu eksekusi yang realistis.
  • Walaupun ada batas atas, jika nilainya terlalu besar maka secara praktis tidak berbeda dari loop tak berujung.

3. Larangan alokasi memori dinamis setelah inisialisasi

  • Dalam sistem embedded, memori terbatas sehingga tujuannya adalah mencegah crash akibat kehabisan memori.
  • Namun, alokasi dinamis yang dapat diprediksi bisa jadi lebih aman daripada manajemen memori manual.
  • Sebagai contoh, dengan menggunakan real-time garbage collector (RTGC), alokasi dinamis pun dapat dibuat dapat diprediksi.

Kritik:

  • Daripada melarang alokasi dinamis itu sendiri, bisa jadi pendekatan yang lebih baik adalah menganalisis pola penggunaan memori untuk menjamin keamanan.
  • Dengan memanfaatkan alat analisis statis modern (seperti SPlint), kesalahan terkait memori dinamis dapat dideteksi lebih awal.

4. Ukuran fungsi dibatasi tidak lebih dari satu lembar kertas A4 (sekitar 60 baris)

  • Logikanya, fungsi yang terlalu panjang akan menurunkan keterbacaan.
  • Namun, di lingkungan pengembangan modern ada fitur code folding, sehingga ukuran unit logis lebih penting daripada panjang fungsi.

Kritik:

  • Yang seharusnya dijadikan acuan adalah kompleksitas logis, bukan ukuran fisik (jumlah baris).
  • Memecah fungsi menjadi kecil-kecil itu sendiri tidak boleh menjadi tujuan → justru bisa membuat pemeliharaan lebih sulit.

5. Minimal gunakan dua pernyataan assert per fungsi

  • assert sangat berguna untuk debugging dan dokumentasi.
  • Namun, pembatasan jumlah yang kaku bisa tidak efisien.

Kritik:

  • Yang penting bukan jumlah assert, melainkan memperjelas lokasi yang memang memerlukan validasi data.
  • Memvalidasi semua argumen dan input eksternal lebih praktis.

6. Minimalkan scope objek data

  • Ini prinsip yang baik karena mendorong penggunaan variabel lokal.
  • Namun, bukan hanya fungsi, scope tipe dan fungsi juga perlu diminimalkan.

Kritik:

  • Dalam Ada, Pascal, JavaScript, dan bahasa fungsional, tipe dan fungsi juga dapat dideklarasikan secara lokal → pendekatan yang lebih baik daripada aturan NASA.

7. Wajib memvalidasi nilai balik fungsi dan validitas parameter

  • Nilai balik harus selalu diperiksa.
  • Namun, memeriksa semua kasus secara menyeluruh sulit dilakukan dalam praktik.

Kritik:

  • Untuk mencegah kesalahan saat runtime, pemeriksaan sebanyak mungkin memang diperlukan, tetapi batas praktis juga harus dipertimbangkan.
  • Terutama di C, pemeriksaan nilai balik sangat penting, tetapi dalam bahasa modern (Java, Rust, dll.), ini bisa ditangani lebih aman dengan memanfaatkan sistem tipe.

8. Batasi penggunaan preprocessor (hanya include header dan makro sederhana yang diizinkan)

  • Makro kompleks, token pasting, dan makro variadik (...) dilarang.
  • Namun, makro variadik bisa berguna sebagai alat debugging.

Kritik:

  • Daripada membatasi penggunaan preprocessor, lebih baik menganjurkan gaya makro yang mudah dibaca.
  • Jika kompilasi kondisional seperti #ifdef dilarang, menulis kode yang independen dari platform bisa menjadi sulit.

9. Batasi penggunaan pointer (larangan pointer ganda, larangan function pointer)

  • Larangan penggunaan function pointer → bertujuan mencapai stabilitas yang tinggi.
  • Namun, function pointer sangat penting untuk callback, strategy pattern, dan device driver.

Kritik:

  • Jika pemilihan fungsi dipaksa lewat switch-case tanpa function pointer, keterbacaan kode menurun dan pemeliharaan menjadi sulit.
  • Dalam pengembangan sistem operasi, network stack, dan driver, function pointer adalah hal yang esensial.
  • Daripada membatasi pointer, metode yang menjamin penggunaan pointer secara aman (seperti smart pointer C++ atau Rust) adalah solusi yang lebih baik.

10. Untuk semua kode, aktifkan peringatan compiler pada tingkat maksimum dan gunakan alat analisis statis

  • Aturan ini adalah rekomendasi yang sangat baik.
  • Menghilangkan peringatan compiler + menggunakan alat analisis statis = peningkatan stabilitas.

Kritik:

  • Aturan NASA lainnya (misalnya larangan pointer, pembatasan ukuran fungsi) pada dasarnya bertujuan mengatasi keterbatasan alat analisis statis.
  • Namun, karena alat analisis statis modern sudah sangat berkembang, memanfaatkan teknik analisis yang lebih canggih lebih berguna daripada menerapkan pembatasan yang berlebihan.

6 komentar

 
regentag 2025-02-18

Semuanya memang terlihat bisa dipahami dan diperlukan jika dilihat dari sudut pandang real-time dan embedded. Apakah penganalisis statis bisa menggantikan aturan-aturan ini?

Misalnya, jika alokasi dinamis diizinkan, apakah bisa dijamin bahwa alokasi memori akan berhasil dalam semua skenario penggunaan?

Kalau mempelajari pengujian perangkat lunak, selalu ada dalil yang disebut pada hari pertama jam pertama. Salah satunya adalah bahwa "pengujian yang sempurna itu mustahil".

 
smboy86 2025-02-18

Karena yang menentangnya lebih menarik perhatian saya,
sepertinya aturan ini tidak cocok dengan saya, haha

 
rtyu1120 2025-02-17

Sepertinya bukan hanya NASA, di industri yang berkaitan langsung dengan keselamatan jiwa seperti penerbangan/otomotif juga cukup sering diterapkan aturan coding yang mirip haha

 
ssssut 2025-02-17

https://github.com/kubernetes/kubernetes/…
Di antara kode sumber Kubernetes, ini mengingatkan saya pada blok kode bergaya "space shuttle style" yang katanya ditulis mengikuti cara penulisan kode sumber aplikasi NASA Space Shuttle.
Thread HN terkait: https://news.ycombinator.com/item?id=18772873

 
GN⁺ 2025-02-17
Komentar Hacker News
  • Jika membaca artikel aslinya, setiap poin dijelaskan tujuannya
  • Artikel asli terutama menargetkan bahasa C, dan tampaknya dioptimalkan agar keandalan aplikasi penting yang ditulis dalam C bisa diperiksa dengan lebih ketat
  • Penulis aslinya jelas sangat paham apa yang ia lakukan, dan menjelaskan berbagai cara untuk memverifikasi kode C
  • Logika dalam artikel asli sepenuhnya dapat dipahami
    • Mungkin karena saya belajar C pada sistem kecil
    • Saya belajar C untuk perangkat keras bagi implan medis, dan di laboratorium kami juga mengikuti pedoman serupa
  • Paragraf terakhir sangat bagus
    • Aturannya mungkin terasa ketat pada awalnya, tetapi kita harus mempertimbangkan kasus ketika nyawa bisa bergantung pada ketepatan kode
    • Seperti sabuk pengaman mobil, awalnya mungkin terasa tidak nyaman, tetapi lama-kelamaan akan menjadi hal yang alami digunakan
  • Kritik saya terhadap aturan ini akan sangat berbeda dari OP
    • Sulit bagi saya untuk sejak awal menganggap serius tulisan yang membela setjmp/longjmp
    • Pola ini jelas bermasalah bagi siapa pun yang pernah mendekatinya
    • Tulisan itu mengklaim bahwa setjmp/longjmp adalah penanganan pengecualian
    • Juga mengklaim bahwa penanganan pengecualian itu baik
    • Ada masalah serius pada premis kedua
  • Artinya adalah menetapkan jumlah iterasi maksimum untuk loop
    • 10^90 itu konyol dan tidak relevan
    • Saya berhenti membaca setelah sampai pada bagian ini
  • Jika mengkritik aturan ini, saya akan fokus pada hal-hal berikut
    • Panjang isi fungsi tidak berkorelasi dengan kesederhanaan pemahaman, dan bahkan bisa kebalikan dari yang disiratkan aturan itu
    • 2 assertion sepenuhnya arbitrer, dan kita seharusnya menambahkan assertion untuk semua hal yang bisa diassert
    • Orang yang memakai Ada, Pascal (Delphi), JavaScript, atau bahasa fungsional sebaiknya mendeklarasikan tipe dan fungsi selokal mungkin
  • Pendekatan pribadi saya di JavaScript adalah tidak mendefinisikan fungsi secara bertingkat kecuali jika saya memang ingin menangkap nilai secara eksplisit
    • Mungkin ini karena model mental lama
    • Dalam profiling performa, dulu terlihat bahwa fungsi didefinisikan ulang setiap kali dipanggil
    • Saya rasa interpreter JavaScript modern tidak lagi bekerja seperti itu
    • Sejak diperkenalkannya arrow function, mungkin sudah ada optimasi mendalam
    • Kebiasaan lama tidak mudah hilang
    • Fungsi bernama yang tidak menangkap variabel lokal saya biarkan tetap berada di cakupan file/modul
  • Banyak catatan lain menarik dan sangat detail
    • Para engineer lama menyukainya dengan gaya "secara teknis akurat adalah jenis akurasi terbaik"
    • Saya rasa nada kehati-hatian umum yang ingin disampaikan aturan NASA ini sangat baik, dan saya mendukung sebagian besarnya
  • Dalam konteksnya, ini lebih merupakan praktik yang disarankan daripada "aturan"
    • "Aturan" formal ada dalam dokumen dengan nama seperti "NPR"
    • Developer tidak berkewajiban untuk mematuhi atau mengabaikan "aturan" ini
  • GCC bisa memberikan penggunaan stack serta hubungan caller-callee setelah kompilasi
    • setjmp() dan longjmp() adalah cara yang buruk untuk menangani pengecualian
    • Kode pembersihan tidak akan dijalankan
    • Jika mengikuti semangat aturannya, seharusnya tidak ada sumber daya yang memerlukan pembersihan
  • Masalah utamanya muncul secara berbeda pada tiap aplikasi
    • Apa yang harus dilakukan ketika batas iterasi terlampaui atau ketika sumber daya tetap yang dialokasikan saat startup tidak mencukupi
  • Tidak jelas mengapa ukuran kertas tidak lagi relevan hanya karena programmer sekarang membaca kode di layar
    • Ada pembahasan berulang tentang ukuran halaman dan ukuran karakter standar
    • Itu bukan hanya soal keterbatasan kertas, tetapi juga keterbatasan manusia
  • Aturan tentang rekursi dimaksudkan untuk menjamin batas yang diketahui secara statis atas ruang stack yang dibutuhkan
    • Kritik bahwa ini bergantung pada compiler memang benar, tetapi itu adalah prasyarat untuk menurunkan batas atas saat runtime
    • Sistem yang kritikal terhadap keselamatan memerlukan waktu respons yang terjamin
  • Judulnya seharusnya menunjukkan bahwa ini adalah kritik terhadap aturan tersebut
  • Menganjurkan penggunaan tipe yang ketat
    • Penggunaan tipe yang ketat untuk semua tipe skalar
    • Jangan mencampur satuan imperial dan metrik
 
roxie 2025-02-21

> Judul harus menunjukkan bahwa ini adalah kritik terhadap aturan tersebut

222