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.