regles de codage

publicité
PRINCIPES DE PROGRAMMATION
EN C
.
OBJECTIFS

.
REGLES DE CODAGE





OBJECTIFS
POURQUOI DES REGLES
LES REGLES POUR QUEL LANGAGE
VUE GLOBALE
REGLES DIVERSES
DES REGLES POURQUOI ?

LISIBLE
– STRUCTURER



MAINTENABLE
PORTABLE
EVITER LES PROBLEMES
DES REGLES POUR QUELS
LANGAGES


C, la référence
PASCAL, le compromis avec le passé
– VAX, BSO, OREGON



ASSEMBLEUR, un combat dépassé
ADA, pour les pros
C++, la nouvelle référence
LES QUALITES VISEES








faible couplage externe
forte cohésion interne
bonne décomposabilité
bonne composabilité
bonne compréhensibilité
non ambiguïté
portabilité
testabilité
FAIBLE COUPLAGE ET FORTE
COHESION
BONNE DECOMPOSABILITE
BONNE COMPOSABILITE
NOTATION COD-CNN/X

CATEGORIE C
–
–
–
–
–
–

S REGLE DE STRUCTURATION
P REGLE DE PRESENTATION
D REGLE SUR LES DONNEES
I REGLE SUR LES INSTRUCTIONS
G REGLE GENERALE
O REGLE DE PROGRAMMATION ORIENTEE OBJETS
OBLIGATION X
– O REGLE OBLIGATOIRE
– T|R REGLE RECOMMANDEE
– F REGLE FACULTATIVE
CHOIX DES REGLES



DANS LES NORMES DE DEVELOPPEMENT
OU LE PLAN DE DEVELOPPEMENT
EN COMPLETANT LA GRILLE ANNEXE
EN FONCTION DES NIVEAUX, FUTURE
NOTATION [12 ]COD-CNN
– 1,2,3 EN SOULIGNE : OBLIGATOIRE
– 1.,2,3 EN NORMAL : RECOMMANDEE
– 1,2,3 REMPLACE PAR UN ESPACE : FACULTATIF
CHOIX DES REGLES

(G01/O) Une dérogation à une règle de
codage doit faire l'objet d'une justification.
Une dérogation à une règle de codage doit
être accompagnée de mesures
complémentaires pour compenser la perte de
qualité.
CONCEPTION PRELIMINAIRE



ARCHITECTURE LOGIQUE
ARCHITECTURE DYNAMIQUE
ARCHITECTURE PHYSIQUE
ARCHITECTURE PHYSIQUE



METHODE STRUCTUREE : DECOMPOSITION
EN MODULES FONCTIONNELS
METHODE OBJET : DECOMPOSITION EN
OBJETS
COMPOSANT = MODULES FONCTIONNELS
OU OBJETS
ARCHITECTURE PHYSIQUE


Décomposition en composants
Spécification des composants
LOGICIEL
ELEMENT
ELEMENT
ELEMENT
COMPOSANT
COMPOSANT
ELEMENT
COMPOSANT
COMPOSANT
ELEMENT
COMPOSANT
COMPOSANT
L'ARTICLE

DONNEE =
– CONSTANTE
– ou TYPE
– ou VARIABLE

ou TRAITEMENT
– SOUS-PROGRAMME (FONCTION/PROCEDURE)
– ou TACHE
– ou MACRO
COMPOSANT = MODULE



GROUPE/ENSEMBLE D'ARTICLES
A FORTE COHESION INTERNE
A FAIBLE COUPLAGE
PROPRIETE D'UN ARTICLE

(S01/O) Tout article doit avoir une définition
unique à laquelle tous les utilisateurs se
réfèrent.
– > DEFINITION DANS DES FICHIERS INCLUS
– > OU GERE PAR LE LANGAGE (EX ADA)
– > OU GERE PAR UN OUTIL (EX OSCAR)

(S02/F) La propriété d'un article est donnée à
un composant et un seul.
– > DEFINITION GLOBALE/EXPORTABLE DANS UN SEUL
COMPOSANT
– > REFERENCE EN EXTERNE/IMPORTE DANS LES
COMPOSANTS UTILISATEURS
COMMENT REGROUPER LES
ARTICLES


POUR AVOIR BEAUCOUP D'ARTICLES
LOCAUX
POUR AVOIR PEU D'ARTICLES
GLOBAUX/EXPORTABLES
S03 = SOLUTION IDEALE A
S01+S02

(S03/F) Chaque composant est constitué
d'une interface et d'un ou de plusieurs corps.
Chaque élément comporte une interface. Ces
interfaces contiennent les déclarations
accessibles de l'extérieur.
UTILISATEURS
UTILISATEURS
UTILISATEURS
INTERFACE
CORPS
SEPARATION
INTERFACE/CORPS EN C/C++
M1.H
#include M1.H
M1.C
M2.H
#include M2.H
M2.C
SI M2 UTILISE M1
M1.H
#include M1.H
M1.C
M2.H
#include M2.H
#include M1.H
M2.C
TYPE GLOBAL
M1.H
typedef definition m1_type;
#include M1.H
M1.C
M2.H
#include M2.H
#include M1.H
M2.C
m1_type variable;
VARIABLE GLOBALE
M1.H
extern m1_type m1_variable;
#include M1.H
m1_type m1_variable;
M1.C
M2.H
#include M2.H
#include M1.H
M2.C
m1_variable = 4;
FONCTION GLOBALE
M1.H
[extern] void m1_fnc(void);
#include M1.H
void m1_fnc()
{
M1.C
}
M2.H
#include M2.H
#include M1.H
M2.C
m1_fnc();
IMPORTATION DANS
L'INTERFACE

(S05/T)L'interface d'un composant ne doit
faire référence à l'interface d'un autre
composant que si les déclarations de l'autre
composant lui sont nécessaires pour ses
propres déclarations.
#include M1.H
M1.H
typedef definition m1_type;
#include M1.H
M1.C
M2.H
typedef m1_type m2_type[10];
#include M2.H
#include M1.H
M2.C
m1_type variable;
COMMENT EVITER LES
INCLUSIONS MULTIPLES
#ifndef M1
#define M1
#ifndef M2
#define M2
M1.H
#include M1.H
M2.H
typedef definition m1_type;
typedef m1_type m2_type[10];
#endif
#endif
#include M1.H
M1.C
#include M2.H
#include M1.H
M2.C
COMMENT ACCELERER LA
COMPILATION
#ifndef M1
#define M1
M1.H
#ifndef M2
#define M2
#ifndef M1
#include M1.H
M2.H
#endif
typedef definition m1_type;
typedef m1_type m2_type[10];
#endif
#endif
#include M1.H
M1.C
#include M2.H
#ifndef M1
M2.C
#include M1.H
#endif
SEPARATION
INTERFACE/CORPS EN
PASCAL



UTILISABLE EN OREGON, DIGITAL, BSO
PROBLEME : SYNTAXES INCOMPATIBLES DE
DECLARATION D'INTERNES ET D'EXTERNE
SOLUTION : UTILISER DEUX VERSION
D'INTERFACE
– M1.DEF -> M1.REF
– GENERER LE SECOND A L'AIDE D'UN OUTIL
TRANSDEFREF
SEPARATION
INTERFACE/CORPS EN
PASCAL trans_def_ref
trans_def_ref
M1.DEF
M1.REF
M2.DEF
M2.REF
include M1.DEF
include M2.DEF
include M1.REF
M1.C
M2.C
SEPARATION
INTERFACE/CORPS EN ADA

IMPOSEE PAR LE LANGAGE
M1.ADS
M2.ADS
with M1
M1.ADB
M2.ADB
UTILISATION DE PLUSIEURS
LANGAGES

(S04/T)En cas d'utilisation de plusieurs
langages, un composant utilisé doit posséder
une interface dans le langage du composant
utilisateur.
M1.H
M1.REF
M2.DEF
#include M1.H
include M2.DEF
include M1.REF
M1.C
M2.PAS
UTILISATION D'ASSEMBLEUR

(S09/T)les sous-programmes assembleurs
globaux doivent respecter les conventions de
passage des paramètres du langage évolué
utilisé.
M1.inc
M1.h
include M1.inc
M1.ASM
M2.H
#include M2.h
#include M1.h
M2.C
INTERFACE





DEFINITION DES ARTICLES
EXPORTABLES/GLOBAUX DU COMPOSANT
ISSUS DE LA CONCEPTION PRELIMINAIRE
PEUT ETRE ECRIT DES LA CONCEPTION
PRELIMINAIRE
PEUT ETRE INCLUS EN ANNEXE DE LA
CONCEPTION PRELIMINAIRE
(P01/O) le cartouche d'une interface est
imposé
INTERFACE : LES RUBRIQUES
D'ENTETE









NOM DU COMPOSANT
MEMORISATION DE LA DEFINITION
CODE D'IDENTIFICATION
REUTILISABILITE
DESCRIPTION
DEROGATION
AUTEUR
HISTORIQUE
VISIBILITE/COMPOSANTS IMPORTES
INTERFACE : LES
EXPORTATIONS






(S06/O) Seuls les articles (constante, variable,
type, fonction) potentiellement utilisables par
plusieurs composants peuvent être exportés.
DECLARATIONS DE CONSTANTES
DECLARATIONS DE TYPES
DECLARATION DE VARIABLES
DECLARATION DE PROTOTYPE DE
FONCTIONS
DECLARATION DE MACROS-FONCTIONS
LE(S) CORPS : LES RUBRIQUES





(P06/F) le format du cartouche d'un corps de
composant est imposé
NOM DU COMPOSANT
IMPORTATION DE L'INTERFACE
HISTORIQUE
COMPOSANTS IMPORTES
CORPS : LES DEFINITIONS





DONNEES EXPORTABLES
CONSTANTES LOCALES
TYPES LOCAUX
VARIABLES ET CONSTANTES LOCALES
FONCTIONS LOCALES
LES CONSTANTES





MACRO : #define les réserver pour les
définitions de dimension (ex tableau)
(D01/T)Les constantes d'objets complexes
doivent être définies comme des variables
mais avec le préfixe const qui en interdit
toute modification
ex : extern const float Pi;
(D02/F)Pour les listes d'états possibles, la
définition d'un type énumération est
préférable à celle des autres constantes.
ex : enum phase { repos, actif, en_panne };
LES MACROS ATTENTION
DANGER


(P02/O)les noms de macros (constantes ou
fonctions) doivent être écrites en majuscule,
les autres identificateurs devant comporter au
moins un caractère minuscule.
ELLES NE SONT PAS MASQUABLES PAR
DES DECLARATIONS LOCALES
LES MACROS ATTENTION
DANGER



(P05/O) Les arguments des macro-fonctions
doivent être protégés par des parenthèses
pour éviter des erreurs à l'expansion,
SAUF PROTECTION PAR DES PARENTHESES
IL Y A RISQUE D'ERREUR A L'EXPANSION
(S07/T)L'utilisation de macros doit être
justifiée par la criticité temps d'un
composant.
LES TYPES GLOBAUX


LES ASSOCIER A UN COMPOSANT
REGROUPER LES FONCTIONS AGISSANT
SUR CE TYPE DANS CE COMPOSANT
typedef struct complexe /* définition de l'objet mathématique
{
}complexe;
complexe */
double réel; /* partie réelle */
double imaginaire; /* partie imaginaire */
LES VARIABLES GLOBALES

LIMITER LES VARIABLES GLOBALES
– LES REGROUPER DANS DES STRUCTURES

(P03/F)Le premier caractère d'une variable
exportable sera en majuscule, tous les autres
caractères devant être en minuscule. Une
variable locale sera entièrement constituée de
minuscules.
LES FONCTIONS

(P04/O) Une déclaration (prototype) est
obligatoire pour un sous-programme, dans
une interface :
- Elle doit être précédée par une
description du sous-programme..
- Tous les arguments doivent être
nommés et renseignés avec au moins une
ligne par argument. (sauf la partie variable
dans le cas d'un nombre variable
d'arguments) et le type de l'argument (entrée,
sortie, entrée/sortie, valeur de retour)
LES FONCTIONS
ex de prototype :
/* addition de deux complexes */
complexe complexe_add(
complexe source1,
/* entrée : opérande source */
complexe source2
/* entrée : 2é opérande source */
);
/* retour : résultat de l'addition */
LES FONCTIONS

(I01/O) Dans un prototype de fonction
- Le type 'void *' doit être réservé à la
manipulation de bloc binaire de bas niveau.
- Le prototype d'une fonction sans
argument doit s'écrire : void fnc(void);
LES FONCTIONS





(P07/F) Le format du cartouche par sousprogramme est imposé.
NOM
DESCRIPTION
FONCTIONS APPELEES
DONNEES EXTERNES UTILISEES
LISIBILITE









A. PROGRAMMATION STRUCTUREE
B. BOUCLES
C. PARENTHESAGE
D. REGLES DE NOMMAGE
E. REGLES DE TYPAGE
F. COMPLEXITE
G. ASSEMBLEUR
H. MOTS RESERVES
I. RACCOURCIS D'ECRITURE
PROGRAMMATION
STRUCTUREE

(P08/O)Le code et le pseudo-code doivent
être structurés et commenté, ses structures
doivent être mises en évidence par des
indentations.
PROGRAMMATION
STRUCTUREE

(P09/T) consignes de structuration du code et
du pseudo-codestructuration
- l'instruction de fin de bloc doit être
alignée sous l'instruction de début de bloc,
- le bloc d'instruction doit être décalé
(indentation),
- chaque bloc doit comporter au
minimum un commentaire,
- une ligne comporte au plus une
instruction,
- les expressions longue doivent être
évitées ou réparties sur plusieurs lignes.
PROGRAMMATION
STRUCTUREE
/* commentaire sur l'instruction complète */
if ( i == 2 )
{
/* commentaire sur la branche */
action2();
}
else if ( j == 3 )
{
/* commentaire sur l'autre branche */
action();
}
UTILISATION DES
INSTRUCTIONS DE RUPTURE

I03/T) Les instructions de rupture de
séquence doivent correspondre ou
synthétiser une structure de contrôle de la
conception détaillée. L'instruction GOTO ne
peut pas en faire partie, elle ne peut que
synthétiser.
autorisations :
pseudo-code
instructions de ruptures
autorisées
...............................................................................
...............................................................................
...............................................................................
BOUCLE


(I04/O)Le traitement d'une boucle doit rester
dans le corps de la boucle.
Une boucle complexe doit être exprimée sur
plusieurs lignes
for( i=0,j=10;
/* valeurs initiales */
(i<=10) && (état==OK); /* condition de maintien */
i++ , j-- )
/* passage à indice suivant*/
{
tab1[i] = tab2[j];
printf("%d\n",i);
}
BOUCLE
int status = FALSE;
/* initialisation ok ? */
for(i=0;
(i<=10) && (status==FALSE;)/* bon test de maintien?*/
i++)
{
debut_de_traitement;
if(condition)
{ if( erreur() )
status = TRUE; /* bonne affectation ? */
else
traitement;
}
if( ! status )
/* bon test ? */
fin_de_traitement;
}
suite;
for(i=0; i<=10; i++)
{
debut_de_traitement;
if(condition)
{ if( erreur() )
break;
traitement;
}
fin_de_traitement;
}
suite;
LISIBILITE / PRESENTATION



(P10/T)Les expressions doivent être
parenthèsées
(P12/T) Tous les articles exportables doivent
être préfixés par le code d'identification du
composant propriétaire.
(P13/T) Le nom d'un fichier doit être préfixé
par son code d'identification.
LISIBILITE / PRESENTATION



(P11/F) les opérateurs non standards suivants
sont interdits :
++ -+= -= *= /= %= >>= <<= &= ^= |=
affectation à l'intérieur d'une expression
affectation conditionnelle ? :
ex : tab[i*2][j*3+k][l] += 4;
au lieu tab[i*2][j*3+k][l] = tab[i*2][j*3+k][l] + 4;
LISIBILITE DES DONNEES




(D03/F)Il faut typer toutes les données
(D07/T)l'utilisation du type standard 'entier'
est interdite
(D04/F)Déclarer dans le fichier portab.ext les
redéfinitions de types standards, avec 'ext'=
extension utilisé pour les fichiers inclus dans
le langage .
(D05/O)Le signe du type 'char' dépend d'une
option de compilation, le préfixe 'signed' ou
'unsigned' est donc obligatoire sur ce type.
LISIBILITE GENERALITE


(G02/O)il ne doit pas être tenu compte de
l'implémentation du compilateur
(G03/F)Il faut fixer les limites admises pour la
complexité d'un composant sur les mesures
suivantes :
- niveau maximum d'imbrications (<=6)
- nombre d'instructions par sousprogramme (<=100)
- nombre de sous-programmes par
composant (<=7)
- nombre d'instructions par ligne (<=1)
LISIBILITE / INSTRUCTIONS


(I08/T)L'usage d'instructions assembleurs
dans le code C doit être justifiée et n'est
autorisé que sous forme de macro-fonction
définie dans le fichier "portab.h" pour des
traitements qu'il serait impossible d'écrire en
langage évolué..
ex #define MASQUER_CPU #asm("move
#2700,SR")
LISIBILITE / INSTRUCTIONS


(I02/F)Les mots réservés nouveaux non
supportés, comme const, volatile, noalias,
doivent être déclarés comme macro dans le
fichier portab.h.
ex #define volatile
SECURITE










A. AIGUILLAGE
B. SORTIE DE FONCTION
C. CONDITION D'EMPLOI DU GOTO
D. EFFETS DE BORD
E. PASSAGE D'ARGUMENTS
F. OPTIONS DE COMPILATION
G. L'OUTIL DE GENERATION
H. MEMOIRE DYNAMIQUE
I. RECURSIVITE
J. REENTRANCE
AIGUILLAGE


(I05/T) une instruction d'aiguillage doit
toujours comporter une branche 'autre/par
défaut'
(I06/T)Toutes les branches d'un aiguillage
(switch) doivent apparaître au même niveau et
doivent comporter l'instruction 'break'.
switch(valeur_testee)
{
case cas_1 : traitement_1;
break;
...
case cas_n : traitement_n;
break;
default : traitement_autres_cas;
break;
}
SORTIE DE FONCTION

(I09/T) Les sorties multiples sont interdites
pour l'assembleur
USAGE DU GOTO
**
**

L'instruction GOTO
sert exclusivement
à coder une
instruction du
pseudo-code
inexistante
dans le
langage utilisé
SI alarme alors
TST ALARME
BEQ OK
**
**
**
afficher le message d'erreur
PEA MSGERR
JSR ERREUR
ADD #4,SP
BRA SUITE
**
** sinon
**
traitement
**
OK: JSR TRAITEMENT
**
** finsi
**
SUITE:
EFFETS DE BORD


(I07/O)les instructions pouvant provoquer des
ambiguïté suivant l'ordre d'évaluation sont
interdites
ex : tab[i++] = tab[i++];
PASSAGE D'ARGUMENT
(D06/O)Lors d'un passage d'argument par
adresse, le paramètre formel pointeur doit
être qualifiés par le préfixe 'const' sauf s'il est
nécessaire de le modifier dans la fonction. Un
argument qui ne doit pas être modifié par la
fonction doit également être préfixé.

void fnc(
/* fonction quelconque */
int * const pt_argument_retour)
{
*pt_argument_retour = 0; /* raz argument */
pt_argument_retour = 0; /* erreur à la compilation*/
}
PASSAGE D'ARGUMENT
void fnc( /* fonction quelconque */
const struct x * const pt_struct_entree)
{
}
...
i = pt_struct_entree->a;
pt_struct_entree->a = 4;/* erreur à la compilation*/
OPTIONS DE COMPILATION



(G04/O)Les options de compilation et
d'assemblage ne doivent pas être
sélectionnées manuellement mais indiquées
dans le fichier de génération
(G05/T)Les tests (unitaires, d'intégration,
validation) doivent être réalisées avec les
mêmes options de compilation que celles de
la version livrée.
(G06/T)Les options permettant des contrôles
à l'exécution (ex domaine d'activité des
variables) doivent être activées.
WARNINGS

(G09/T) Seuls les messages d'avertissement
(warnings) suivants sont tolérés lors de la
génération :
.........................................................
.........................................................
.........................................................
.........................................................
OUTIL DE GENERATION




(G07/O)Un outil de génération de l'application
est obligatoire (make ou mms), ou par défaut
un fichier de commande
fixer les options de compilation pour
l'application,
indiquer les règles de dépendance et ne
recompiler que les modules modifiés,
spécifier la version d'outil utilisé.
PROGRAMMATION AVANCEE

(G08/F)L'utilisation de la mémoire dynamique
est délicate en temps réel. Les points
suivants doivent être vérifiés :
- exclusion mutuelle d'accès en
multitâches,
- pas d'algorithme de recompactage de la
mémoire en temps réel
- temps d'allocation et de désallocation
fixes et connus,
- traitement obligatoire des cas de
saturation,
- test de la légalité de la désallocation.
PROGRAMMATION AVANCEE

(S08/T) L'utilisation de la récursivité doit
s'accompagner des précautions suivantes :
- nombre d'activations borné,
- connaissance des besoins en mémoire
locale.
ANNEXES

APPLICATION AUX AUTRES LANGAGES
– C non ANSI
– FORTRAN
– POUR LE PASCAL ET L'ASSEMBLEUR VOIR LES
AUTRES MANUELS
– PROCHAINEMENT POUR ADA ET C++

NORMALISATION
– A. NORMES CIVILES
– B. NORMES MILITAIRES




LISTE DES REGLES
MATRICE REGLES/PROPRIETES
RULES FOR C LANGUAGE
OUTILS D'AIDE
Téléchargement