Conseils de Codage en C-FR
Conseils de Codage en C-FR
Conseils de Codage en C-FR
Un livre de Wikilivres.
==
==
==
Chaque fichier source (.c, .h) et chaque fonction C doivent être précédés
Justification Livre
Exemple
/*******************************************************
Nom ......... : limites.c
Role ........ : Affiche les caractéristiques numériques
pour les types du langage C
Auteur ...... : Thierry46
Version ..... : V1.1 du 10/3/2008
Licence ..... : GPL
Compilation :
gcc -Wall -pedantic -std=c99 -o limites.exe limites.c
Pour exécuter, tapez : ./limites.exe
********************************************************/
Outils
Justification
La maintenance et la relecture des sources sont facilités par une présentation homogène.
Exemple (extrait)
//...
// Teste si les valeurs lues sont les valeurs attendues.
for (i=0; i<(int)nbInt; i++)
{
(void)printf("%d, ", valIntLu[i]);
if ( valIntLu[i] != valInt[i] )
{
(void)printf("Au lieu de %d\n", valInt[i]);
exit(EXIT_FAILURE);
}
}
Outils
L'outil UNIX indent permet d'améliorer la présentation des fichiers sources écrits en C. De nombreuses
options permettent de paramètrer le style de ses sorties. Elles peuvent être passées sur la ligne de
commande ou mieux dans un fichier de configuration spécifique.
Justification
Augmente la lisibilité.
Justification
Augmente la lisibilité.
Justification
Dans le domaine numérique, le programmeur écrit des formules compliquée juxtaposant de nombreuses
fonctions et opérateurs.
Le langage C permet de mélanger tests, appel de fonctions, opérations.
Le code parait, à première vue, plus compact, plus efficace. Il faut cependant décomposer les lignes longues
en plusieurs, en utilisant des variables intermédiaires. Les compilateurs récents se chargeront d'optimiser
efficacement le code pour vous. Le résultat sera plus facile à comprendre par d'autres. Les problèmes de
priorité pourraient être atténués.
Justification
Dans un fichier source, permet des distinguer rapidement les constantes des variables.
Exemple
#define LONGUEUR_NOM_FICHIER 15
#define STR(s) #s
#define XSTR(s) STR(s)
Justification
Les lignes courtes seront plus faciles à comprendre par une personnes chargée de maintenir le logiciel.
Exemples
Mauvais :
Meilleur :
#define sonne(N) \
{ \
int n; \
for (n=N; n>0; n--) fputc(0x7, stderr); \
}
//...
(void)printf("\nProgramme %s, fichier source "__FILE__
"\nCompile le "__DATE__" a "__TIME__"\n",
argv[0]);
Évitez les noms trop courts sans signification fonctionnelle : v, vv, vvv...
Ne différenciez pas deux identificateurs uniquement en changeant la casse de certains caractères : Fichier,
fichier.
Ne différenciez pas deux identificateurs uniquement par un nombre trop restreint de lettres.
N'utilisez pas de caractère souligné en tête ou en fin d'identificateur.
Utiliser une règle de nommage cohérente dans le projet : mot séparés par des soulignés
(fichier_parametres_calcul) ou mots collés commençant par des majuscules sauf première lettre
(fichierParametresCalcul).
Justification
Justification
Justification
Améliore la lisibilité du code. argv[0] représente le nom de lancement du programme et peut être utilisé
pour les messages d'erreur. La récupération des arguments du programme pourra se faire avec les fonctions
getopt(), getsubopt().
Justification
Exemple
Justification
Justification
Rend le code plus lisible et évite les erreurs lors de l'ajout d'une instruction dans un bloc qui n'en contient
qu'une seule.
Exemple
Mauvais :
Meilleur :
if (test == 2)
{
for (i=0; i<n; i++)
table[i] = 1;
table2[i] = 2;
}
/* Suite... */
L'instruction table2[i] = 2; donne faussement l'impression de faire partie de la boucle for, ce qui est
renforcé par l'indentation et l'accolade fermante du if.
Si table2 était dimensionné à n, les indices acceptables iraient de 0 à n-1 inclus. Lors de l'exécution de
l'instruction table2[i] = 2;, i vaudrait la valeur n, ce qui provoquerait l'écriture d'une valeur hors de
l'espace mémoire réservé pour le tableau table2.
Il s'en suivra :
Le débordement hors de l'espace utilisateur qui provoquera une violation mémoire : Sanction rapide par
arrêt du programme exception SIGSEGV.
L'écrasement du contenu d'un autre pointeur situé juste après l'espace table2 qui lorsqu'il sera utilisé plus
tard (100 lignes plus bas ?) provoquera une autre catastrophe : Cette erreur peut être difficile à détecter
sans l'utilisation d'un outil qualité d'analyse dynamique.
Ces erreurs peuvent arriver aléatoirement selon le système, le compilateur utilisé ou le chargement du
programme en mémoire.
Justification
Permet de mieux repérer les blocs d'instructions conditionnelles, les corps de boucles surtout en cas de
structures imbriquées.
Exemple
int table[nbLigne][nbCol];
for(int ligne = 0; ligne < nbLigne; ligne++)
{
for(int col = 0; col < nbCol; col++)
{
table[ligne][col] = ligne + col;
}
}
// Impression
for(int ligne = 0; ligne < nbLigne; ligne++)
{
for(int col = 0; col < nbCol; col++)
{
(void)printf("table[%d][%d] = %d,",
ligne, col, table[ligne][col]);
}
(void)puts("");
}
return EXIT_SUCCESS;
}
Justification
(c_lis_16)
Il faut déclarer chaque variable séparément et non les unes à la suite des autres, séparées par des virgules.
Justification
La déclaration de plusieurs variables dans une même instruction peut provoquer des erreurs de type pour les
variables.
Une déclaration séparée permet aussi de décrire dans un commentaire en bout de ligne le rôle de chaque
variable.
Exemple
// Declaration incorrecte :
// nomFicSortie est de type char au lieu de char * et ne peut donc être initialisé à NULL
char *nomFicEntree = NULL, nomFicSortie = NULL;
// Meilleur
char *nomFicEntree = NULL; // Fichier de parametres du calcul
char *nomFicSortie = NULL; // Fichier pour les points calcules
VG : de 1 à 20
STMT : de 1 à 100
FCOM : de 0,2 à 1,2
AVGS : de 2 à 10
Justification
VG trop élevée montre qu'une fonction est trop complexe et mériterait d'être décomposée en plusieurs ou
réanalysée.
STMT trop élevée indique que la fonction est trop longue. Il faudrait la diviser ou peut-être appeler des
fonctions.
FCOM : Habituellement les programmes ne sont pas assez commenté : FCOM faible. Cependant un
programme avec trop de commentaires peut aussi montrer des problèmes (trop de ruses d'un expert qui
Justification Fiabilité
Des noms de variable trop courts et souvent sans signification (a, n, x...) ne Pour la robustesse
permettent pas aux relecteurs de faire la relation entre l'identificateur Pour les performances
informatique et la réalité représentée. La recherche des variables est alors Pour la sécurité
difficile et les risques d'avoir deux identificateurs dont les portées se
superposent sont augmentés. Qualité
Modifier le sommaire
Sortie de boucle (c_rec_2)
La sortie d’une boucle (do, while, for) doit se faire par la condition de test.
Justification
Un algorithme bien conçu ne doit pas nécessiter de sortie prématurée dans le corps de boucle. La
programmation structurée permet d'éviter le style spaghetti des premiers programmeurs. Ce mode de
programmation ancien rendait le suivi du déroulement difficile à l'aide d'un débugueur. Il fallait mettre des
points d'arrêt sur chaque sortie de boucle potentiel. La logique du programme était très difficile à
appréhender par la personne chargée d'effectuer des modifications.
Les instructions goto, continue, break (hors switch) sont donc vivement déconseillées.
Exemple
free(table[i]);
}
Justification
L’instruction for doit permettre le contrôle total d’une itération. Si une instruction est vide, cela veut dire
que la boucle aurait pu être écrite sous une autre forme (do ou while).
Justification
Cette règle évite les erreurs d’interprétation dues aux règles d’associativité du langage C. Son non respect
peut conduire à des erreurs dans le codage des expressions mathématique ou de test.
Exemple
On veut tester si n est pair : n & 1 effectue un ET logique de bit entre n et 1, mais l'opérateur relationnel ==
est prioritaire par rapport à &, l’expression ( n & 1 == 0 ) sera donc toujours fausse.
Justification
Lors du remplacement des paramètres formels par les paramètres effectifs, il peut y avoir des problèmes de
priorité des opérateurs dans les expressions résultats.
Exemple
Justification
Au-delà de 5 instructions, le déroulement est assimilable à un traitement, et doit faire partie intégrante d’une
fonction. De plus, les macros instructions ne permettent pas un contrôle strict de leurs paramètres.
Si l'utilisation d'une fonction entraîne une dégradation des performances, il faut recourir à l’inlining. Le mot
clé C99 inline répond à ce problème.
Justification
Le résultat est bien souvent imprévisible par suite des effets de bord, surtout en cas de répétition du
paramètre dans la définition de la macro.
Justification
Lorsqu'un fichier d'entête (.h) est inclus plusieurs fois directement, un test en son début permet d'éviter les
erreurs de compilation dues à des déclarations répétées :
Exemple
#ifndef GRAPHIQUE_H
#define GRAPHIQUE_H
// corps du fichier d’en-tête
// ...
#endif
Justification
Facilite l’analyse des sources, évite de superposer les erreurs de priorité des opérateurs arithmétiques à ceux
des opérateurs relationnels.
Justification
Facilite l’analyse. Permet un meilleur contrôle de la correspondance arguments - paramètres. La norme C99
interdit de transgresser cette règle.
Outils
Le contrôle du peut être effectué en utilisant le compilateur C avec options les plus strictes ou un outils
qualité comme lint ou splint.
Justification
Lorsque plusieurs entités sont désignées par le même nom et ne peuvent être distinguées que par leur
position par rapport aux structures de contrôle, cela réduit la lisibilité du code et favorise l’apparition
d’erreurs, en particulier lors de la maintenance du source.
// Première déclaration de i
int i = 0;
// ...
{
// Deuxième déclaration de i
int i = 0;
// ...
i++;
// ...
}
Si la deuxième déclaration de i est supprimée, alors il y a un risque pour que l’incrémentation ne le soit pas,
ce serait alors la variable déclarée hors du bloc qui serait utilisée, ce qui ne serait pas le comportement
souhaité. Le code resterait alors valide et aucun problème ne serait détectée.
Selon le compilateur, il est possible que les données const soient stockées dans une zone accessible en
lecture, mais pas l’écriture.
Justification
L’utilisation abusive de pointeurs est la source de graves dysfonctionnements très difficiles à détecter. Les
programmeurs habitués à d’autres langages sont souvent perdus face à certaines subtilités du C. Pour les
parcours de tableaux, il est préférable d’utiliser des indices (tab[i]) au lieu du déréférencement par pointeur.
Justification
Justification
Les types int a[] et int* a sont complètement différents, même si, une fois déclarés, leur usage parait
identique. Le programmeur doit être particulièrement vigilant : par exemple, beaucoup d’éditeurs de liens
confondraient un int* a et un int a[] définis dans deux modules (.o) différents. Ceci est susceptible de
provoquer une erreur fatale.
Exemple
La variable “ a ” occupe 6 octets dans l’espace de la mémoire dynamique. Cette zone sera désallouée lorsque
la variable sortira de son espace de validité. La variable p occupe 4 octets (taille courante d’un pointeur).
Elle est un pointeur qui référence une région de la mémoire non modifiable. Une nouvelle valeur peut être
affectée à “p”, mais pas à “a”. En fait, un bon compilateur devrait imposer ici le type const char*.
Facilité de modification
Un programme est souvent amené à être modifié, adapté, réutilisé par celui Conseils de codage en C
qui l'a écrit ou par un autre, sur une longue durée (correction d'erreur,
Sommaire
évolution du logiciel, réutilisation dans une autre application...).
Maintenabilité
Ces conseils visent à réduire les efforts nécessaires lors d'évolutions.
Pour la lisibilité
Pour la détection des erreurs
Éviter les constantes littérale (c_mod_1) Pour des modifications plus faciles
Les constantes chaîne, numérique doivent être représentées par des Fiabilité
symboles. Les constantes littérales sont interdites.
Pour la robustesse
Justification Pour les performances
Pour la sécurité
Les constantes littérales dupliquées et réparties dans le code source rendent
les modifications plus difficiles : risque d'altération, d'oubli d'une Qualité
occurrence. Il faut les regrouper sous formes de constantes symboliques
(définition du pré-processeurs) en tête de fichier source ou dans des fichiers Pour une utilisation plus facile
inclus. Pour la qualité numérique
Exemple Livre
Justification
La personne, qui relira le code source en vue de sa maintenance, aura besoin de comprendre les grandes
étapes de l'algorithme, les fonctions réalisées par la suite d'instructions du langage.
Exemple
Mauvais :
// Incrémentation de i
i = i + 1
Meilleur :
Justification
La valeur par défaut d’une variable dépend de facteurs qui peuvent échapper au programmeur. Cette règle
évite les fonctionnements aléatoires de certains programmes.
Outils
Les compilateurs et les outils de vérifications statiques comme splint émettent des avertissements en cas de
problème. Certains compilateurs possèdent des options pour générer tous les avertissements sous forme
d'erreur, ce qui permet d'interrompre une chaîne de compilation afin de corriger le code.
Justification
La duplication de source oblige à intervenir à plusieurs endroits pour corriger une erreur.
Rend le code source moins maintenable.
Lire plusieurs fois le même code ralentit sa compréhension.
Les parties dupliquées doivent être fusionnées en une seule. Le code commun, éventuellement paramétré,
deviendra une fonction. Si des contraintes de performance l'impose, l'inlining pourra être utilisé.
Outils
La recherche des parties dupliquées pourra se faire avec un outil de recherche de chaînes de caractères : sous
UNIX grep ou à l'aide d'un éditeur s'il permet la recherche de texte dans plusieurs fichiers.
Justification
Les variables globales peuvent être modifiées par plusieurs unités de compilation, le contrôle des
modifications est donc très délicat, les effets de bord sont possibles (modifications non désirées d'une
variable ou d'une zone mémoire par du code lié). Un trop grand nombre de variables externes dénote une
mauvaise analyse des interfaces entre unités de compilation ou une mauvaise gestion de la portée des
variables.
Le mot-clé static en C permet, entre autres, de limiter la portées d'une variable globale ou d'une fonction à
son seul fichier source. Il garantit que ces fonctions ou variables ne seront pas utilisées, par erreur, par
d’autres unités. Les fonctions locales pourraient être masquées ou masquer d’autres fonctions de même nom,
mais définies ailleurs dans le projet ou dans une bibliothèque liée. Le comportement du programme pourrait
alors dépendre de l’ordre dans lequel les objets et bibliothèques sont présentés à l’édition de lien. Le respect
de cette règle allégera l’édition de lien et évitera certains effets de bord.
Outils
Recherche dans les fichiers sources des mots clés extern, des déclarations de variables hors des fonctions.
L'utilitaire Unix nm et ses options -g et -o permet de connaître les symboles externes dans les résultats de
compilation (modules objets .o, bibliothèques .a, .so).
Utiliser les fonctions et bibliothèques écrites par d'autres programmeurs, principalement dans :
Justification
Le respect de ce conseil limite le nombre de lignes de code à maintenir ainsi que les efforts nécessaires aux
tests du logiciel.
Justification
Contrôle
Rechercher des instructions return et exit à l'aide d'un utilitaire comme grep.
Justification
Améliore la portabilité.
Justification
Écrire le corps de fonction dans un fichier .h et l’inclure dans plusieurs sources dupliquerait ce code et
pourrait provoquer des erreurs due aux symboles définis plusieurs fois. Plutôt que d’utiliser le
pré-processeur, il faut répartir le code source dans différents fichiers .c qui seront compilés séparément et
réunit lors de l’édition de lien.
AVGS : Taille moyenne des instructions, calculée à partir du nombre d'opérateurs et d'opérandes distincts.
LEVL : Nombre maximal d'imbrications des structures de contrôle (for, while, if...) de la fonction plus un.
VOCF : Fréquence d'utilisation du vocabulaire dans un composant, défini par la formule : F_VOC =
(N1+N2)/ (n1+n2) avec :
N1 est le nombre d'occurrence des opérateurs,
N2 est le nombre d'occurrence des opérandes,
n1 est le nombre opérateurs distincts,
n2 est le nombre opérandes distincts.
CALL : Nombre d’appels distincts : Nombre total d'appels de fonctions effectués dans la fonction
analysée.
AVGS : de 2 à 10
LEVL : de 1 à 5
VOCF : de 1 à 4
CALL : de 0 à 7
Justification
AVGS : Les instructions trop longues sont difficiles à modifier. Elles peuvent provoquer des problèmes de
priorité des opérateurs, des conversions de type involontaires.
LEVL : Un trop grand nombre d'imbrication de structures de contrôle pourra être une source d'erreur en
cas de modification d'un programme. Il faut déplacer certains niveaux dans une fonction.
VOCF : Un vocabulaire qui se répète trop pourra être dû à des copiés-collés abusifs de parties de code ou
à un programmeur à jeu d'instruction réduit. Les modifications à apporter devront alors s'appliquer à de
nombreux endroits. Une solution consiste à factoriser le code à l'aide de fonction paramétrées ou à
réutiliser du code externe développé et validé (bibliothèques spécifiques).
CALL : Une valeur trop élevée montre une mauvaise hiérarchisation dans la fonction. Un nombre élevé de
fonctions appelée et de paramètres augmente le nombre de combinaisons possibles dans le déroulement du
programme. Il faut limiter le nombre d'appel au besoin en découpant la fonction.
Il faut utiliser des outils de qualité qui permettent d'effectuer encore plus de Fiabilité
contrôle.
Pour la robustesse
Il faudra ensuite comprendre les messages puis corriger les sources afin Pour les performances
d'éliminer tous ces avertissements. Pour la sécurité
Justification Qualité
Cette pratique permet d'obtenir des logiciels plus robustes et plus portables Pour une utilisation plus facile
Justification
Permet de traiter les cas non prévus explicitement en détectant les cas dégradés dus à des valeurs
inattendues.
Exemple (extrait)
//...
while ((optc = getopt_long (argc, argv, "htvm", longopts, (int *) 0)) != EOF)
{
switch (optc)
{
case 'v':
v = 1;
break;
case 'h':
h = 1;
break;
case 'm':
m = 1;
break;
default:
unknown = 1;
break;
}
}
Outils
Les outils de vérification statique, comme splint, émettent un warning lorsqu'une clause default est
oubliée.
Un comptage des mots clés des mots switch et default dans un éditeur de texte ou avec les outils grep et
wc d'UNIX.
Justification
des problèmes dans leur déroulement : validité des paramètres, erreurs de calcul...
des erreurs dues à l’environnement du logiciel : non - conformité de l’arborescence des fichiers, droits
d’accès, ressources non disponibles...
Une bonne habitude consiste à caster en void tous les appels à des fonctions dont on souhaite ignorer les
codes retour. Cette pratique facilite les contrôle avec les outils qualité.
Exemple
//...
hFile = fopen(NOM_FIC, "r");
if (hFile == NULL)
{
perror("Erreur");
(void)fprintf(stderr,
"Impossible d'ouvrir %s en lecture\n",
NOM_FIC);
exit(EXIT_FAILURE);
}
Outils
Les outils de contrôle statiques comme splint émettent un warning lorsqu'un codes retour de fonction n'est
pas testé ou explicitement ignoré.
Justification
Une ressource non libérée après utilisation peut n'être libérée qu'à la fin de l'application. Mais auparavant,
celle-ci limite les ressources disponibles du système et si le code est appelé plusieurs fois, une erreur de
ressource peut se produire (pas assez de mémoire, ...).
Outils
Un certain nombre d'outils permet de détecter les fuites mémoires et de voir l'occupation des ressources.
Mais avant tout, il faut avoir un code de gestion des ressources correct :
Tester le code de retour de la fonction d'allocation, et ne pas exécuter le reste du code en cas d'échec,
Libérer la ressource quoi qu'il se passe, en un seul endroit du code afin d'éviter de libérer plusieurs fois la
même ressource, et si possible dans la même fonction que l'instruction d'allocation.
Mettre à NULL le pointeur sur la structure de contrôle du fichier (file handle) pour éviter la l'utilisation
ultérieure d'une ressource invalide.
Exemple
//...
hFile = fopen(NOM_FIC, "r");
if (hFile == NULL)
{
perror("Erreur ouverture fichier");
(void)fprintf(stderr,
"Impossible d'ouvrir %s en lecture\n",
NOM_FIC);
exit(EXIT_FAILURE);
}
else
{
erreur = traiterFichier(hFile);
if (fclose(hFile) != 0)
{
perror("Erreur fermeture fichier");
}
hFile = NULL;
}
Le traitement du fichier est délégué dans une fonction séparée. Celle-ci pouvant alors retourner un code
d'erreur avec l'instruction return sans se soucier de fermer le fichier ouvert, vu qu'il sera fermé juste après
l'appel à la fonction.
Justification
Améliore la stabilité et la fiabilité du logiciel. Évite les erreurs provenant de la poursuite du traitement avec
des données d’entrée invalides.
Justification
Traitement efficace des retours d'erreurs qui peuvent en étant considérée comme des valeurs de sortie
normale entraîner des catastrophes.
Le langage C implémente les assertion à l'aide d'une macro : assert(condition) qui en plus est débrayable.
Justification
Vous devez utiliser ce mécanisme d'assertion pour construire des programmes plus robustes et faciliter la
maintenance et la relecture du code.
Lorsque vous concevez une fonction, vous identifiez des invariants : des conditions qui doivent toujours être
vérifiées pour pouvoir exécuter le traitement ou fournir des résultats utilisables. Par exemple pour une loi
physique : une température doit toujours être supérieure ou égale à 0 Kelvin.
Vous coderez ces conditions sous forme d'assertion. En phase de mise au point, si une assertion n'est pas
vérifiée, le programme ne doit pas se poursuivre. Lors de la phase de test, lorsqu'une assertion n'est pas
vérifiée, le programmeur doit alors coder un mécanisme permettant de présenter un message d'erreur clair ou
un contournement qui permettra de continuer. Les assertions qui n'auront pas été déclenchées en fin de
période de test seront laissées dans les sources.
Performances
Ces conseils permettent d'obtenir des programmes plus rapides ou utilisant Conseils de codage en C
seulement les ressources nécessaires.
Sommaire
Maintenabilité
Éviter d'éparpiller les entrées-sorties (c_perf_1)
Pour la lisibilité
Il faut éviter d'effectuer des entrées sorties dans une partie du programme Pour la détection des erreurs
qui réalise des calculs de façon intensive. Il faut regrouper ces opérations Pour des modifications plus faciles
d'échange dans une partie consacrée à l'initialisation ou à l'écriture et la
communication des résultats. Fiabilité
Les instructions issues de la compilation des fichiers sources sont exécutées par un processeur, mais pas de
façon simultanée. Certaines opérations prennent plus de temps que d'autres.
Exemple
Pour trier un grand nombre d'information, utiliser un algorithme de tri rapide de type Quick Sort comme
qsort de la librairie C standard. plutôt qu'un tri bulle.
Pour des calculs mathématiques (matrices, algèbre linéaire), utiliser des bibliothèques spécialisées.
Sécurité
L'application des conseils suivants rendent les logiciels plus sécurisés : Conseils de codage en C
moins vulnérables aux attaques.
Sommaire
Maintenabilité
Pas d'affichage direct (c_sec_1)
Pour la lisibilité
Il faut éviter d'afficher une chaîne provenant de l'utilisateur (argument de Pour la détection des erreurs
programme, de fonction, contenu d'un fichier) en l'employant comme Pour des modifications plus faciles
premier argument des fonctions printf.
Fiabilité
Justification
Pour la robustesse
Pour les performances
Améliorer la sécurité en évitant le plantage du programme.
Pour la sécurité
Exemple Qualité
Le mauvais exemple : Pour une utilisation plus facile
Pour la qualité numérique
/* prog.c */
#include <stdio.h> Livre
#include <stdlib.h>
L'argument pour le %s n'étant pas fourni explicitement, le programme risque d'afficher le contenu de la
mémoire à une adresse indéfinie, voire retourner une erreur de segmentation.
Le bon exemple :
/* prog.c */
#include <stdio.h>
#include <stdlib.h>
Exemple : %s
Il faut :
soit afficher des étoiles ou points (ou tout caractère fixé) lors de la frappe,
soit ne rien afficher du tout.
Justification
Améliorer la sécurité en évitant que les mots de passe d'un utilisateur ne soient visibles aux autres (poste
public, lieu de travail, ...), et éviter une opération intempestive de presse papier contenant le mot de passe
(envoi d'une copie d'écran par exemple).
Outil
Certaines librairies graphiques possèdent des champs de saisie spéciaux pour les mots de passe, d'autres
librairies possèdent des fonctions de saisie de mots de passe sur la console.
Pour la saisie par console, si aucune fonction spéciale existe, il faut désactiver l'affichage de la saisie tant
que l'utilisateur n'a pas fini sa saisie.
Le codage est plus efficace lors de l’utilisation des nouvelles fonctionnalités Fiabilité
introduite par la norme (mot-clé restrict, type de taille fixe, tableau de taille
Pour la robustesse
variable (VLA), boolean...).
Pour les performances
Le programme sera plus facile à reconstruire et à porter sur une autre Pour la sécurité
machine dans le futur.
Qualité
Tout chemin d’accès figé est interdit (c_exp_2) Pour une utilisation plus facile
Pour la qualité numérique
Les chemins d'accès aux fichiers ne doivent pas être écrits en dur dans les
fichiers sources. Livre
Justification Programmation C
Un programme doit être paramétrable sans avoir à modifier ses fichiers Modifier le sommaire
sources et le recompiler.
Les chemins d'accès aux ressources doivent être récupérés depuis l’environnement ou depuis des fichiers de
configuration : de préférence dans un format auto-décrit et éditable : comme XML.
Justification
L'utilisateur doit pouvoir les comprendre : par leur langue, par leur vocabulaire.
Ils doivent lui permettre de corriger le problème ou de contacter un support technique.
Ils doivent proposer éventuellement un moyen de contournement, une cause probable.
Leur contenu doit différer selon qu'ils sont destinés à l'utilisateur ou à la personne qui assure la
maintenance.
Ils doivent permettre par un moyen (fichier de log par exemple) de fournir à la maintenance le plus
possible d’informations : version du programme, date, nom de l’utilisateur, plate forme, nom de fonction,
Justification
Exemple
Justification
Outils
Une analyse des appels systèmes en cours d'exécution du logiciel peut se réaliser avec un utilitaire comme
strace pour UNIX ou ktrace sur Mac. Analyse des modifications du système de fichiers.
Qualité numérique
L'application de ces règles doit permettent d'éviter des erreurs de calcul. Conseils de codage en C
Sommaire
Types homogènes dans les calculs (c_num_1) Maintenabilité
Une expression arithmétique ne doit comporter que des éléments du même Pour la lisibilité
type. Pour la détection des erreurs
Pour des modifications plus faciles
Justification
Fiabilité
Évite les erreurs de calcul dues aux règles de conversions implicites des
langages. C’est le programmeur qui doit définir explicitement les Pour la robustesse
conversions de type. Les conséquences du mélange d'opérandes de même Pour les performances
type : Pour la sécurité
Exemple
Livre
n ne vaut pas -1 à la fin, mais une valeur du genre : 2147483647, ce qui faussera beaucoup les calculs
ultérieurs , pour avoir un résultat correct il aurait fallut écrire n = n/(int) u;
Outils
Les compilateurs et les outils de contrôle statique comme splint émettent des avertissements.
a = a +1 dans une boucle peut produire la valeur a = 9.999999999 au lieu de 10.0, une instruction du genre
if (a==10.0) ne fonctionnera pas comme prévue.
Au lieu de if ( A == B )
Écrire if ( fabs( A - B ) < EPS ) EPS est une valeur très petite qui dépend de la précision de la
machine, utiliser si disponible des constantes symboliques définies sur le système.
Outils
Les compilateurs et les outils de contrôle statique comme splint émettent des avertissements.
Annulation: Erreur qui se produit lors de la soustraction de deux valeurs trop proches.
Absorption : Erreur qui se produit lorsqu'on additionne deux valeurs d'un ordre de grandeur trop différent.
Ce phénomène est sensible lorsqu'on réalise l'opération un grand nombre de fois.
Arrondi : pertes de chiffres significatifs dans la partie décimale du nombre.
Justification
L'ensemble mathématique des décimaux, déjà plus restreint, est infini en étendue : il contient les nombres
compris entre plus à moins l'infini. L'écart entre deux nombres peut être infiniment petit. Par contre les
nombres en machine sont stockés dans un espace mémoire de taille très limité (32, 64, 128 bits...). Les
nombres y sont représentés par une mantisse et un exposant codés sur un nombre fini de bits. On pourrait
comparer le domaine de représentation des nombres en machine à une tranche de gruyère pleine de trous.
Les résultats trop grands ou trop petits sont tronqués ou changent de signe.
Une valeur trop petite peut être ignorée lorsqu'elle est additionnée à un grand nombre.
La différence entre deux nombres peut être considérée comme nulle alors que ces nombres sont différents.
Il faut parfois réorganiser les expressions numériques et leur ordre de calcul pour éviter ces erreurs.
==
Je m'appelle Thierry.
France ∇
J’habite en France.
Je m'intéresse à la qualité des logiciels.
Cet utilisateur a pour langue
Ma page principale se trouve sur Wikipédia Utilisateur:Thierry46 fr maternelle le français.
Contributions
Exercices en langage C
Programmation C
Conseils de codage en C
Autres projets
Sur Wikiversity : v:fr:utilisateur:Thierry46
Sur Wikipedia : w:fr:utilisateur:Thierry46
Sur Wikimedia Commons : c:user:Thierry46
==
Bonjour !
Babel
Wikilivres Wikipédia Wikinews Wikiversity Wiktionnaire
Cet utilisateur a pour langue Wikiquot
fr maternelle le français.
Présentation
Wikisource Commons Wikispecies Meta MediaWiki Incubator
France ∇
Je viens de France.
Administrateur
Je fais partie des administrateurs du
Wikilivres francophone
( vérifier (https://fr.wikibooks.org
/w/index.php?title=Sp
%C3%A9cial:Listusers&limit=1&
fr en es en en en en
username=Conseils_de_codage_en_C
/Version_imprimable) ; voir mon élection ).
Bureaucrate
Je fais partie des bureaucrates du
Reporter un bug de mediawiki Wikilivre francophone
Utilisateur SUL ∇
Cet utilisateur a créé un compte global et
son compte principal est sur Wikilivres
français .
Wiki-bricoleur
Je bricole des modèles
et des gadgets.
Éclair...
ou Éclair...cie en ce moment ?
Récupérée de « https://fr.wikibooks.org/w/index.php?title=Conseils_de_codage_en_C
/Version_imprimable&oldid=441443 »