Condition encapsulé ou EXIT_FAILURE

Fermé
LInus - 27 juin 2014 à 21:38
ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 - 29 juin 2014 à 16:54
Bonjour,

Lorsqu'on test des conditions (par exemple si un fichier existe bien ou si l'utilisateur a rentré les bon arguments) qui pénalise la suite du programme si elles sont fauses, est-ce qu'il faut mieux avoir un modele comme ça :

if(condition1)
{
/* Code */
if(confition2)
{
/* Code */
if(condition3)
/* Code */
else
printf("Error\n");
}
else
printf("Error\n");
else
printf("Error\n");
ou alors comme ca :

if(!condition1)
{
printf("Error\n");
exit(EXIT_FAILURE);
}
/* Code */
if(!condition2)
{
printf("Error\n");
exit(EXIT_FAILURE);
}
/* Code */
if(!condition3)
{
printf("Error\n");
exit(EXIT_FAILURE);
}
/* Code */
Je sais que vous allez me dire que sa revient au même, mais je voulais savoir avec qu'elle solution vous coder. Je trouve que la solution 1 n'est pas très adapté à ceux qui indente de 4 à chaque nouvelle condition (comme moi), ce qui fait qu'à la fin on se retrouve avec de gros blanc en début. Mais la deuxième solution, on quite le programme avec un EXIT_FAILURE. En gros, on stop nette le programme sans le faire arriver à la fin. Donc quel est la meilleur, ou la mieux adapté à un code clair et lisible.

3 réponses

ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 225
28 juin 2014 à 15:14
'lut, perso je prend la 2e solution pour les mêmes raisons que toi: l'indentation excessive et une déstructuration du code en résultant.
Mais moi, je créerais plutôt une fonction pour faire le traitement, et ferait un
return
d'un
int
ou autre code d'erreur (ou une exception si c'est du C++), plutôt que de quitter le programme d'office, sans avoir eu le temps de nettoyer (fermeture de fichiers,
free()
s, etc); et c'est la fonction appelante qui sort le message d'erreur, et éventuellement la fonction appelée peut sortir des infos de debug.
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
28 juin 2014 à 15:23
Bonjour,

Comme gravgun, je préfère la seconde solution.

Pour moi un if tout seul, c'est un cas particulier, qui nécessite un traitement spécifique en plus du cas général. Pour une exception c'est parfait
Alors qu'un if avec un else c'est vraiment un branchement, une division en deux du cas général, ce qui est plutôt rare pour des gros morceaux de codes.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
28 juin 2014 à 21:54
Bonjour,

Clairement la deuxième, sinon tu ne peux pas faire une bonne gestion des erreurs.
Mais, il y a d'autres variantes plus propres.
Déjà, il faut savoir qu'il y a deux théories : SESE (Single Entry Single Exit) vs SEME(Single Entry Multiple Exits).
Les deux se tiennent.
Ensuite, tu peux également utiliser goto pour ne pas trop complexifier le code.

Ce qui donnerait par exemple (en reprenant exactement ton exemple) :
int fin=0;
if (! condition1)
     goto erreur;
if (! condition2)
     goto erreur;
if (! condition3)
     goto erreur;

fin=1;
if (! fin) {
     /*ici tu gères tes erreurs*/
     if (!condition1 || !condition2 || !condition3) {
          fputs("Error\n", stderr);
     }
}

return ...;

Bien sûr, tu peux (et tu n'auras pas le choix dans des cas plus compliqués) traiter tes erreurs différemment selon les conditions.

Cdlt,
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
28 juin 2014 à 23:33
Je viens de voir que j'ai oublié le label "erreur" dans mon exemple. Il faut le mettre entre "fin=1;" et "if (!fin) {"
0
ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 225
29 juin 2014 à 11:47
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 29/06/2014 à 14:24
Non gravgun...
C'est le mal dans 95% des cas (car emploi à mauvais escient)... Cela rend le code difficile à lire.
Mais dans la gestion des erreurs, c'est très utilisé et conseillé.
Retiens cette règle : "on ne doit jamais utiliser goto sauf pour la gestion des erreurs" ;-)
0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié par KX le 29/06/2014 à 14:48
Je suis un peu rouillé en C, mais il n'y a pas du tout de mécanisme d'exception ? Dans la plupart des langages que je connais on a des throw/try/catch, en C il n'y a vraiment rien d'autre que les goto ?
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
29 juin 2014 à 15:00
KX,
Rien d'automatique en C :-).
En revanche, il est possible de sauvegarder et restituer le contexte avec setjmp/longjmp. Et donc, de faire soi-même son gestionnaire d'erreurs. Mais, on les emploie finalement assez rarement.
0