La fiabilité d'un code source informatique

Rédigé par niconux Aucun commentaire
Classé dans : C/C++, Développement Mots clés : Code, fiabilité, développement

Dans un précédent article, traitant de SonarQube, j'avais évoqué le sujet de la mesure de la qualité d'un code source.

Steve McConnell a écrit un livre "Code Complete" où il évoque les principes de programmation utiles pour la construction de logiciels.

Dans une section de son livre, il est question des "erreurs attendues" (error expectations). En somme le nombre de bugs par lignes de code.

Il montre que la fiabilité d'un code source peut être classée selon différentes catégories.

Voyons ça plus en détails.

Un code source n'est jamais exempt de bugs, selon le nombre de bugs par ligne de code, il peut répondre à certaines exigences.

Dans le milieu industriel

En moyenne on trouve entre 15 et 50 erreurs par 1000 lignes de code. Ce taux d'erreur montre que le code a atteint un certain niveau de programmation structurée, mais inclus problablement aussi un mix de différentes techniques de développement.

Dans les applications Microsoft

En moyenne on trouve entre 10 et 20 erreurs par 1000 lignes de code lors des premières versions d'un projet et 0.5 erreur par KLOC (KLOC = 1000 lignes de code) dans la version finale d'un produit.

Ce taux d'erreur montre qu'il y a combinaison de technique de  relecture de code et de tests indépendants.

L'approche "Cleanroom development".

Harlan Mills pionnié du développement "Cleanroom development" (développement en salle blanche) montre qu'il est possible avec sa méthode de développement d'atteindre un taux en dessous de 3 erreurs par KLOC lors des developpements internes et 0.1 erreur dans la version finale d'un projet.

 

 

Peu de projet, comme celui de la NASA avec le développement du logiciel de la navette spatiale, ont atteint le taux de 0 erreur par 500 000 lignes de code.

Ce taux montre qu'il y a l'utilisation conjointe de différentes techniques : comme l'approche d'une norme de developpement stricte, de tests statistique ainsi que de relectures systématique par des pairs.

Vous pouvez retrouver certaines informations sur le développement de ce projet à ces adresses :

Un ingénieur du Jet Propulsion Laboratory (JPL) de la NASA, Gerard J. Holtzman, a récemment publié un guide au sujet de la programmation pour les applications critiques .

Il met en exergue le fait que les règles doivent permettent au code d'être analysé et validé à la main et par des outils automatisés, ce qui est rarement le cas pour les autres guides de programmation qui tendent à être arbitraires, incohérents et à grossir de plus en plus au fur et à mesure des versions.

Dix grandes règles de programmation ont été identifiées. Elles s'appliquent en premier lieu au langage C qui est le langage utilisé au JPL, mais elles peuvent pour la plupart s'appliquer d'autres langages.

Règle 1 : Limitez l'intégralité du code à des structures de contrôle simples – n'utilisez pas les instructions goto, setjmp ou longjmp, et les récursions directes ou indirectes.

Règle 2 : Toutes les boucles doivent avoir une borne supérieure fixe. Il doit être très facile pour un outil de vérification de prouver statistiquement que le nombre possibles d'itérations ne peut dépasser une borne supérieure prédéterminée. Si cette limite ne peut être prouvée statiquement, la règle doit être considérée comme violée.

Règle 3 : N'utilisez pas l'allocation dynamique après l'initialisation de la variable.

Règle 4 : Aucune fonction ne doit être plus longue que ce qui peut être imprimé sur une simple feuille A4 avec une ligne par instruction et une ligne par déclaration. En pratique, cela implique de ne pas avoir plus de 60 lignes de code par fonction.

Règle 5 : Chaque fonction doit comporter au minimum deux assertions. Les assertions sont utilisées pour vérifier des conditions anormales qui ne devraient jamais se produire en condition réelle. Les assertions doivent toujours être dénuées d'effets de bord et devraient être définies comme des tests booléens. Lorsqu'une assertion échoue, une action correctrice explicite doit être lancée, par exemple en renvoyant la cause de l'erreur à l'appelant de la fonction qui exécute l'assertion en échec. N'importe quelle assertion pour lequel un outil de vérification statique peut prouver qu'elle ne peut jamais échouer ou passer viole la règle (i.e. il n'est pas possible de satisfaire la règle en ajoutant d'inutiles instructions assert(true).

Règle 6 : Les variables doivent être déclarées à l'endroit de plus faible porté lexicale.

Règle 7 : La valeur de retour des fonctions doit être vérifiée par chaque fonction appelante, et la validité des paramètres doit être assurée à l'intérieur de chaque fonction.

Règle 8 : L'utilisation du préprocesseur doit être limité à l'inclusion des fichiers en-tête et à des définitions de macros simples. L'ajout d'identificateurs, les listes d'arguments de longueur variable et les macros récursives ne sont pas autorisés. Toutes les macros doivent se développer en unités syntaxiques complètes. L'utilisation des directives de compilation conditionnelle est également douteuse mais ne peut pas être toujours évitée. Cela signifie qu'il est rarement justifié d'avoir plus d'une ou deux directives de compilation conditionnelle même dans des logiciels de grande taille, à l'exception des constructions génériques qui évitent l'inclusion multiple d'un même fichier en-tête. Chacune de ces utilisations doit être signalée par un outil de vérification et justifié dans le code.

Règle 9 : L'utilisation des pointeurs doit être limitée. Plus précisément, pas plus d'un niveau de déréférencement n'est autorisé. Les opérations de déréférencement peuvent ne pas être masquée dans les macros ou dans les déclarations typedef. Les pointeurs de fonction ne sont pas permis.

Règle 10 : Tout le code doit être compilé, dès le premier jour de développement, avec tous les avertissements activés sous les réglages les plus stricts du compilateur. N'importe quel code doit compiler sans avertissement avec ces réglages. Tout le code doit être vérifié quotidiennement avec au moins un, mais de préférence plusieurs, analyseur statique de code source de dernière génération, et ce code doit passer les analyses sans aucun avertissement.

Pour chacune de ses règles, l'auteur fournit un explication disponible dans le document original.

Pour mesurer le taux d'erreurs dans un projet informatique il existe différentes solutions, payant, gratuites, nous avons déja évoqué par exemple SonarQube. Vous pouvez retrouver une liste de solutions pour des projets plus adapté à l'utilisation du langage C à cette adresse : http://spinroot.com/static/index.html

Si vous voulez en savoir plus sur l'ingénierie de fiabilité, n'hésitez pas en jeter un oeil à la page de wikipedia (en anglais, la page française étant très pauvre à ce sujet),

 

 

Écrire un commentaire

Quelle est le dernier caractère du mot 5j13n4 ?

Fil RSS des commentaires de cet article