Bonjour,
Je voudrais dire un mot à propos des goto.
A l'évidence, c'est la plus grosse faute dans ce code. Mais à mon avis le problème va plus loin.
Que veut dire goto : c'est un branchement (généralement inconditionnel). Le langage prévoit plusieurs syntaxe de boucle (for, do, while). Cela signifie que le bloc d'instructions est exécuté un certain nombre de fois, suivant certaines conditions etc.
Le goto est une instruction de branchement, et en aucun cas une instruction faite pour recommencer un traitement.
Il y a une instruction qui efféctue aussi un branchement : switch, mais il s'agit là du cas typique du branchement conditionnel.
Il y a un cas où l'utilisation du goto est tout à fait correcte et donc justifiée. Soit une fonction longue qui est constitué de petits traitements successifs dépendant d'une condition, par exemple l'instruction lue sur un fichier. Pour la clarté de la démonstration, au début de la fonction des espaces mémoire ou autre sont réservés, fichier ouverts etc., au sortir le la fonction ces réservation doivent être libérées, les fichiers fermés etc..
Or, si un bloc de traitement se passe mal, pour quelque raison que ce soit, naturellement il faut sortir de la fonction, mais il faut libérer les réservations. Le goto permet ce type d'écriture de manière complètement sécurisée. Voici le schéma type :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| int Fonction(...)
{
// séquence de réservation d'espace mémoire ouverture de fichier etc
...
//
bool fini=false;
int NumErr=0;
while (!fini)
{
// lecture d'un instruction
string Instruction = Lecture(...);
if (Instruction == Inst1)
{
if (!TraiteInst1(instruction))
{
NumErr=1;
goto FIN;
}
}
if (Instruction == Inst2)
{
if (!TraiteInst2(instruction))
{
NumErr=2;
goto FIN;
}
}
//
// beaucoup de séquences de ce type
//
if (Instruction == Instn)
{
if (!TraiteInstn(instruction))
{
NumErr=n;
goto FIN;
}
}
if (Instruction == Fini)
{
fini = true;
}
} // fin du while
int CodeRetour=0; // c'est bon
FIN: // il n'y a pas de point-virgule
if (NumErr != 0)
{
// on sort en erreur
CodeRetour = NumErr;
}
// Séquence de libération de mémoire, fermeture de fichier etc.
return CodeRetour;
} |
Partager