Carrière, Hardware, IoT / RF, Rust

MISRA-C 2012 : Les 10 règles les plus violées et comment les corriger

MISRA-C 2012 : Les 10 règles les plus violées et comment les corriger

Introduction

MISRA-C:2012 définit 143 directives et règles pour un C sûr en environnement embarqué critique. Voici les violations les plus fréquentes rencontrées lors d’audits de code industriel.

Règle 10.1 — Cast implicite sur opérandes

/* Non-conforme */
uint8_t a = 10u;
uint8_t b = 20u;
uint8_t result = a + b;  // a+b produit un int implicitement

/* Conforme */
uint8_t result = (uint8_t)(a + b);  // Cast explicite requis

Règle 11.3 — Cast pointeur ↔ entier

/* Non-conforme */
uint32_t *reg = (uint32_t *)0x40020000UL;

/* Conforme */
#include <stdint.h>
uintptr_t addr = (uintptr_t)0x40020000UL;
uint32_t *reg = (uint32_t *)addr;

Règle 14.4 — Expression if/while doit être booléenne

/* Non-conforme */
if (get_flag()) { ... }      // get_flag() retourne int
while (uart_ready) { ... }   // uart_ready est uint8_t

/* Conforme */
if (get_flag() != 0) { ... }
while (uart_ready != 0U) { ... }

Règle 15.5 — Un seul return par fonction

/* Non-conforme */
int32_t find(const int32_t *arr, uint8_t len, int32_t val) {
    for (uint8_t i = 0u; i < len; i++) {
        if (arr[i] == val) return (int32_t)i; // return intermédiaire
    }
    return -1;
}

/* Conforme */
int32_t find(const int32_t *arr, uint8_t len, int32_t val) {
    int32_t result = -1;
    for (uint8_t i = 0u; (i < len) && (result == -1); i++) {
        if (arr[i] == val) result = (int32_t)i;
    }
    return result; // Un seul return
}

Règle 17.7 — Valeur de retour doit être utilisée

/* Non-conforme */
memcpy(dest, src, size);
printf("Debug\n");

/* Conforme */
(void)memcpy(dest, src, size);
(void)printf("Debug\n");

Directive 4.6 — Types à taille fixe obligatoires

/* Non-conforme */
unsigned int counter;
long timeout;
char buffer[64];

/* Conforme */
#include <stdint.h>
uint32_t counter;
int32_t timeout;
uint8_t buffer[64u];

Flags GCC pour détecter les violations

CFLAGS += -Wall -Wextra -Wpedantic
CFLAGS += -Wconversion -Wsign-conversion
CFLAGS += -Wcast-align -Wcast-qual
CFLAGS += -Wstrict-prototypes
CFLAGS += -std=c11

Conclusion

MISRA-C n’est pas une contrainte arbitraire — chaque règle prévient une classe de bugs réels. L’adoption progressive, en commençant par les règles obligatoires, améliore significativement la qualité du code sans paralyser le développement.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *