Ce este MISRA?
MISRA (Motor Industry Software Reliability Association) e un consorțiu britanic fondat în 1990 care publică ghiduri de programare sigură. Cel mai cunoscut: MISRA C — un set de ~150 de reguli care interzic constructe periculoase din limbajul C.
Nu e un compilator, nu e un tool — e un document care spune „fă așa, nu face așa". Respectarea lui se verifică cu tool-uri automate (lintere).
Inițial creat pentru industria auto, MISRA e azi standard și în:
- Avionică (DO-178B/C)
- Medical (IEC 62304)
- Feroviar (EN 50128)
- Industrial (IEC 61508)
Structura regulilor
MISRA C:2012 are 3 categorii de reguli și 2 tipuri:
Categorii
| Categorie | Obligație | Exemple | |---|---|---| | Mandatory | Trebuie respectată obligatoriu | Fără excepții | | Required | Trebuie respectată, dar poți cere derogare motivată | Majoritatea regulilor | | Advisory | Recomandată, nerespectarea nu încalcă standardul | Bune practici |
Tipuri
| Tip | Ce verifică |
|---|---|
| Directive | Proces / organizare (ex: "documentați deciziile") |
| Rule | Cod concret (ex: "nu folosi goto") |
Număr de reguli pe versiune
| Versiune | Reguli | |---|---| | MISRA C:1998 | ~93 | | MISRA C:2004 | ~121 | | MISRA C:2012 | ~143 | | MISRA C:2023 | ~150 (revizia 3) | | MISRA C++:2008 | ~228 | | MISRA C++:2023 | ~200 |
Exemple de reguli — pe categorii
Direcții de siguranță
Câteva reguli iconice, grupate pe ce previn:
| Problemă | MISRA | Ce interzice |
|---|---|---|
| Buffer overflow | Regula 18.1 | Pointeri la array-uri fără limită |
| Use-after-free | Regula 18.6 | Acces după free() |
| Null pointer | Regula 16.7 | Dereferențiere fără verificare |
| Întregi | 10.1-10.4 | Conversii implicite între tipuri |
| Bucle | 14.1-15.7 | Bucle infinite fără ieșire, goto, longjmp |
| Memorie | 21.1-21.12 | malloc/free interzis (doar pool-uri) |
| Evaluare | 13.1-13.6 | Efecte secundare în expresii |
| Preprocesor | 20.1-20.14 | #undef, #include condiționat periculos |
Câteva reguli celebre
Regula 14.1 — Bucle trebuie să aibă un contor și o condiție clară:
// ❌ MISRA: bucle infinite fără ieșire explicită
for (;;) { } // permis doar cu break explicit
// ❌ MISRA: modificarea contorului în corp
for (i = 0; i < n; i++) {
i = i + 2; // periculos, greu de urmărit
}
// ✅ MISRA
for (i = 0; i < n; i++) {
if (cond) break;
}
Regula 16.7 — Pointerii se verifică înainte de folosire:
// ❌ MISRA
void process(int *p) {
*p = 5; // p poate fi NULL
}
// ✅ MISRA
void process(int *p) {
if (p != NULL) {
*p = 5;
}
}
Regula 21.3 — Eroare: alocare dinamică interzisă:
// ❌ MISRA
int *buf = malloc(100);
// ✅ MISRA (alocare statică)
int buf[100];
Multe sisteme critice nu permit malloc — odată ce resursele sunt alocate la pornire, nu se mai alocă nimic dinamic pentru a evita fragmentarea heap-ului sau epuizarea memoriei.
Reguli de notare
Regula 8.3 — Toate funcțiile trebuie declarate înainte de folosire:
// ❌ MISRA — foo() e apelat înainte de declarație
void bar() { foo(); }
void foo() { }
// ✅ MISRA
void foo(void); // declarație
void bar(void) { foo(); }
void foo(void) { }
MISRA în practică
Workflow tipic
1. Scrii cod C (respectând conștient regulile)
2. Rulezi un tool static (PC-lint, SonarQube, Coverity)
3. Tool-ul raportează încălcări → le repari
4. Pentru încălcările justificate, scrii derogare
5. Prezinți raportul de conformitate auditorului
6. Auditorul acceptă sau cere corecții
Tool-uri de verificare
| Tool | Gratis? | Acoperire MISRA | |---|---|---| | PC-lint / FlexeLint | ❌ | Aproape completă | | SonarQube | Parțial (community) | ~80% | | Coverity | ❌ | ~90% | | CppCheck | ✅ | ~50% | | Astree | ❌ | Completă (și runtime) | | Polyspace | ❌ | Completă |
MISRA și limbajul C
C e un limbaj periculos din punct de vedere al siguranței. MISRA încearcă să-l facă sigur prin reguli, dar:
┌────────────────────────────────────────────┐
│ C standard │
│ (poți face orice, inclusiv prostii) │
├────────────────────────────────────────────┤
│ MISRA C │
│ (interzice ~20% din C, previne ~90% │
│ din bug-urile comune) │
├────────────────────────────────────────────┤
│ Tool-uri statice │
│ (verifică automat regulile) │
└────────────────────────────────────────────┘
MISRA vs Rust
O comparație directă:
| Caracteristică | MISRA (C) | Rust |
|---|---|---|
| Buffer overflow | Regula manuală + tool | Imposibil la compilare |
| Use-after-free | Regula manuală + tool | Imposibil (borrow checker) |
| Null pointer | Verificare manuală | Opțional (Option<T>) |
| Alocare dinamică | Interzisă (regula) | Sigură prin tipuri (Box, Vec) |
| Cost | Document £50 + tool $1k-50k/an | Gratis |
| Aplicare | Tool extern, post-factum | Compilatorul o face automat |
| Reguli de învățat | ~150 | ~30 (concepte Rust) |
Un program respectă MISRA nu pentru că e corect — ci pentru că e mai puțin probabil să aibă bug-uri. Un program în Rust e corect din punct de vedere al memoriei — garantat de compilator.
Critici
MISRA nu e lipsit de controverse:
- Costul documentației — ghidul oficial nu e gratuit (spre deosebire de SEI CERT C de la CMU, care e gratis și acoperă același domeniu)
- Falsă siguranță — un cod poate fi MISRA-compliant și tot plin de bug-uri logice. MISRA nu previne greșeli de algoritm
- Tool-urile sunt scumpe — verificarea MISRA e dominată de tool-uri comerciale scumpe, ceea ce exclude echipele mici
- Birocrație — derogările, auditurile și documentația adaugă costuri semnificative fără a îmbunătăți neapărat calitatea codului
Concluzie
MISRA e un standard matur și respectat în industriile critice. Dacă scrii C pentru un airbag sau un sistem de frânare, vei respecta MISRA pentru că clientul și auditorul cer asta. Nu e perfect, dar e cea mai bună soluție disponibilă pentru C în siguranță.
Rust e promițător, dar realitatea e nuanțată:
| Nevoie | Ce alegi | |---|---| | Certificare formală (DO-178C, ISO 26262) | C + MISRA + tool-uri scumpe | | Produs mai sigur, fără certificare | Rust e o alternativă excelentă | | Toolchain certificat | Există pentru C (GCC), nu pentru Rust (rustc/LLVM) | | Cost | MISRA: document £50 + tool $1k-50k/an; Rust: gratis |
Rust atinge siguranța memoriei mai bine decât MISRA + C, dar certificarea safety-critical cere mai mult decât siguranța memoriei: traceabilitate, acoperire MC/DC, toolchain calificat — domenii unde C și MISRA au decenii de precedent.