NASA: The Power of 10: Rules for Developing Safety-Critical Code

Başlatan Erol YILMAZ, 06 Ağustos 2026, 16:18:30

Erol YILMAZ

1. Tüm kodları çok basit kontrol akış yapılarıyla sınırlandırın; `goto` deyimlerini, `setjmp` veya `longjmp` yapılarını, doğrudan ya da dolaylı özyinelemeyi (rekürsiyon) kullanmayın.

/* YANLIŞ: Özyineleme (Recursion) veya goto kullanımı */
uint32_t faktoriyel(uint32_t n) {
    if (n <= 1) return 1;
    return n * faktoriyel(n - 1); // İHLAL: Stack boyutu tahmin edilemez!
}

/* DOĞRU: Basit ve öngörülebilir döngüsel yapı */
uint32_t faktoriyel(uint32_t n) {
    uint32_t sonuc = 1;
    for (uint32_t i = 1; i <= n && i <= 12; i++) {
        sonuc *= i;
    }
    return sonuc;
}


2. Tüm döngülere sabit bir üst sınır verin. Bir denetim aracının, döngünün önceden belirlenmiş yineleme üst sınırını aşamayacağını statik olarak kanıtlaması zahmetsizce mümkün olmalıdır. Bir araç döngü sınırını statik olarak kanıtlayamıyorsa kural ihlal edilmiş sayılır.

/* YANLIŞ: Sınırı belli olmayan döngü */
void wait_for_ready(void) {
    while (check_hardware_status() == 0) {
        // İHLAL: Donanım yanıt vermezse sonsuz döngüye girer!
    }
}

/* DOĞRU: Statik olarak kanıtlanabilir üst sınır */
#define MAX_WAIT_CYCLES 1000U

int wait_for_ready(void) {
    for (uint32_t i = 0U; i < MAX_WAIT_CYCLES; i++) {
        if (check_hardware_status() != 0) {
            return 0; // Başarılı
        }
        delay_ms(1);
    }
    return -1; // Zaman aşımı (Hata kurtarma)
}

3. İlklendirme (initialization) aşamasından sonra dinamik bellek tahsisi kullanmayın.

/* YANLIŞ: Çalışma anında malloc/free kullanımı */
void process_telemetry(uint32_t packet_len) {
    uint8_t *buffer = (uint8_t *)malloc(packet_len); // İHLAL: Dinamik bellek!
    if (buffer != NULL) {
        // ...
        free(buffer);
    }
}

/* DOĞRU: Başlatmada ayrılmış statik bellek kullanımı */
#define MAX_PACKET_SIZE 512U
static uint8_t g_telemetry_buffer[MAX_PACKET_SIZE]; // Statik alan

int process_telemetry(uint32_t packet_len) {
    if (packet_len > MAX_PACKET_SIZE) {
        return -1; // Sınır aşımı kontrolü
    }
    // Buffer emniyetle işlenir...
    return 0;
}

4. Hiçbir fonksiyon, her satırda tek bir deyim ve tek bir bildirim yer alacak şekilde standart bir formatta tek bir kağıt sayfasına basılabilecek uzunluktan daha uzun olmamalıdır. Bu durum genellikle fonksiyon başına en fazla 60 satır kod anlamına gelir.


/* YANLIŞ: Tek satıra birden fazla deyim yazmak veya çok uzun fonksiyon */
void compute_data(void) {
    int a = 5; int b = 10; a += b; b *= a; // İHLAL: Çoklu deyim!
}

/* DOĞRU: Her satırda tek bir bildirim veya ifade */
void compute_data(void) {
    int32_t width = 5;
    int32_t height = 10;
    int32_t area = 0;

    area = width * height;
}

5. Kodun doğrulama (`assertion`) yoğunluğu fonksiyon başına ortalama en az iki assertion olmalıdır. Assertion'lar, gerçek çalışmada asla gerçekleşmemesi gereken anormal durumları kontrol etmek için kullanılmalıdır. Assertion'lar yan etkisiz (*side-effect free*) olmalı ve Boolean testler olarak tanımlanmalıdır. Bir assertion başarısız olduğunda, fonksiyonu çağıran yapıya hata durumu döndürmek gibi açık bir kurtarma eylemi gerçekleştirilmelidir. Statik bir denetim aracının asla başarısız olamayacağını veya asla gerçekleşmeyeceğini kanıtlayabildiği her assertion bu kuralı ihlal eder.
/* YANLIŞ: Yan etki içeren assertion ve kurtarma adımının olmaması */
void update_speed(int *speed_ptr) {
    assert((*speed_ptr)++); // İHLAL: Değişkenin değerini değiştiriyor (side-effect)!
}

/* DOĞRU: Yan etkisiz assertion + açık hata kurtarma (explicit recovery) */
int update_speed(const int32_t *speed_ptr, int32_t delta) {
    assert(speed_ptr != NULL);
    assert(delta >= 0);

    // Kurtarma aksiyonu (Recovery Action)
    if ((speed_ptr == NULL) || (delta < 0)) {
        return -1; // Çağıran yapıya açık hata döndürülür
    }

    int32_t new_speed = *speed_ptr + delta;
    return new_speed;
}


6. Tüm veri nesnelerini mümkün olan en küçük kapsam (*scope*) düzeyinde bildirin.

/* YANLIŞ: Döngü sayacının global veya geniş scope'ta bildirilmesi */
int i; // İHLAL: Her yerden erişilebilir global değişken!

void process_array(void) {
    for (i = 0; i < 10; i++) { /* ... */ }
}

/* DOĞRU: Yalnızca kullanıldığı blok içinde bildirim */
void process_array(void) {
    for (uint32_t i = 0U; i < 10U; i++) {
        // 'i' yalnızca bu blok içinde yaşar
    }
}

7. Çağıran her fonksiyon, `void` olmayan fonksiyonların dönüş değerini kontrol etmeli; çağrılan her fonksiyon ise çağıran tarafından sağlanan tüm parametrelerin geçerliliğini denetlemelidir.

/* YANLIŞ: Parametre ve dönüş değeri kontrollerinin atlanması */
void caller(void) {
    read_sensor(NULL); // İHLAL: Dönüş değeri kontrol edilmedi!
}

/* DOĞRU: Çift taraflı doğrulama */
int32_t read_sensor(int32_t *out_val) {
    if (out_val == NULL) { // Çağrılan fonksiyon parametreyi kontrol eder
        return -1;
    }
    *out_val = 42;
    return 0;
}

void caller(void) {
    int32_t val = 0;
    int32_t status = read_sensor(&val); // Çağıran fonksiyon dönüşü kontrol eder
    if (status != 0) {
        handle_error();
    }
}


8. Ön işlemci (*preprocessor*) kullanımı yalnızca başlık dosyalarının dahil edilmesi ve basit makro tanımlarıyla sınırlandırılmalıdır. Simge birleştirme (*token pasting*), değişken sayıda parametre alan listeler (*ellipses*) ve özyinelemeli (*recursive*) makro çağrılarına izin verilmez. Tüm makrolar eksiksiz sözdizimsel birimler olarak genişlemelidir. Koşullu derleme direktiflerinin kullanımı minimum seviyede tutulmalıdır.

/* YANLIŞ: Eksik sözdizimsel birim, token pasting (##) kullanımı */
#define MAKE_FUNC(name) void name##_func(void) { // İHLAL!
#define ADD(a, b) a + b                         // İHLAL: Parantezsiz eksik birim

/* DOĞRU: Tam sözdizimsel birimler ve inline fonksiyonlar */
#define MAX_BUFFER_SIZE (1024U) // Tam sözdizimsel birim

// Karmaşık makrolar yerine tip güvenli inline fonksiyon tercihi
static inline int32_t add_int32(int32_t a, int32_t b) {
    return a + b;
}

9. İşaretçi (*pointer*) kullanımı sınırlandırılmalıdır. Özellikle, tek bir adres çözme (*dereference*) düzeyinden fazlası kullanılmamalıdır. Pointer dereference işlemleri makro tanımları veya `typedef` bildirimleri içine gizlenemez. Fonksiyon işaretçilerine (*function pointers*) izin verilmez.

/* YANLIŞ: Çift pointer (**) veya fonksiyon pointer kullanımı */
int32_t **matrix_ptr;                   // İHLAL: 2 seviye dereference!
typedef int32_t* PINT;                  // İHLAL: Typedef arkasına pointer gizleme
void (*event_handler)(int) = &on_event; // İHLAL: Fonksiyon pointer!

/* DOĞRU: Yalnızca tek seviyeli adres çözme (*p) */
int32_t set_buffer_val(int32_t *p_target, int32_t value) {
    if (p_target == NULL) {
        return -1;
    }
    *p_target = value; // Yalnızca 1 seviye dereference (*)
    return 0;
}


10. Tüm kodlar, geliştirmenin ilk gününden itibaren, mevcut en katı (*pedantic*) ayarda tüm derleyici uyarıları açık şekilde derlenmelidir. Tüm kodlar sıfır uyarı ile derlenmelidir. Ayrıca tüm kodlar her gün en az bir (tercihen birden fazla) güçlü statik kaynak kod analiz aracıyla denetlenmeli ve tüm analizlerden sıfır uyarı ile geçmelidir.

# YANLIŞ: Uyarıların gözardı edildiği standart derleme
gcc -o main main.c

# DOĞRU: Tüm pedantik uyarılar aktif ve hataya dönüştürülmüş (-Werror)
gcc -Wall -Wextra -pedantic -Werror -std=c99 -o main main.c

# Ayrıca günlük statik analiz araçları (Coverity, Cppcheck, SonarQube vb.) 
# sıfır uyarı raporuyla geçmelidir.

X-Fi

bunların hiçbirisi ile uğraşmak istemiyorsanız RUST kullanın  ::ok

 
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

power20

Türkçe RUST  kitabı var mıydı?




 Şaka yaptım. Programlama kitapları hepsi hiç oldu.


Sabah 8de klimalı sakin ortam, sınırsız kahve sınırsız internet.., hızlı bilgisayar.. akşama RUST öğrenilmiş olur?

Gerçekten böyle olabilir mi? Rust veya başka bir şey. Zekaya sor, öğretsin?

C++, PHP, vb korktuğumuz şeyler hepsi oyuncak oldu

Epsilon

Masterını Amerikada yapmış , pyhtonu 8 yıldır kullanan elektronik mühendisi arkadaş ,Github da bir italyanın herşeyi paylaştığı android uygulamayı hatta 2-3 tane de "Bravii süper çalışıyor "yorumlu programı  2 ayda çalıştıramadı.

power20


Benzer Konular (5)