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