* Se connecte à developpez
* Voit que le sujet sur la gestion d'erreur C est passé de 16 à 25 réponse
* Se dit "Nom de dieu, qu'est-ce qu'il s'est passé ? Y-a-t’il eu un débat endiablé très intéressant apportant plein d'information que je ne connais pas ??"
goto est une instruction inutile. La preuve avec Java qui ne supporte pas le goto
Ah p*tain ...
Bon ben je vais me chercher une bière ... ça sera plus intéressant.
Sérieusement Jacti ?
Tu savais aussi que while c'est une instruction inutile ?
Bahoui, on peut remplacer tout les while par des for.
Et en plus, le mot clef while n'existe pas en Go, alors franchement si ça c'est pas de la preuve bétonné !
Pis tant qu'a faire, tu savais aussi que "++" c'est une instruction totalement inutile ?
Ébahoui, on peut remplacer tout les "i++" par des "i += 1".
D'ailleurs, Ruby n'as pas d'opérateur de pré/post incrémentation ! Abahçaalors, j'aurais dû faire avocat, j'aurais perdu aucune affaire.
Bon, histoire de ne pas faire que du Troll, je rajoute une petite brique ainsi que quelques exemple.
Déjà, je considère que les méthodes de gestion d'erreur présenté dans le premier post sont "commune" et "traditionnelle".
Je veux dire par la, c'est que dans 95% des cas, on tomberas sur une gestion d'erreur de ce type.
Ensuite, je suis plutôt partisans d'utiliser toujours la gestion la plus "simple" et la plus "logique".
Je ne suis pas pour faire toujours la même gestion : ça n'as aucun sens de faire une gestion à base de goto si on a aucune variable a nettoyer et aucune action de rollback à faire.
Si en plus la fonction n'est pas susceptible d'évoluer significativement, franchement, c'est ridicule de faire du goto.
Par exemple, quand je fait une structure, je code plusieurs fonctions permettant de gérer/manipuler cette dernière.
Si la structure possède des propriétés à nettoyer, j'ai une fonction "NomStruct_Constructor" et une fonction "NomStruct_Destructor".
Le principe est simple : la première fonction appelé pour toute variable de type dia_s c'est le constructeur, la dernière, c'est le destructeur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| /* dia : dynamic int array */
typedef struct dia {
int *array;
size_t size; /* Array size */
size_t nbElement; /* Number of element in array */
} dia_s;
void Dia_Constructor(dia_s *self)
{
self->array = NULL;
self->size = 0;
self->nbElement = 0;
}
void Dia_Destructor(dia_s *self)
{
free(self->array);
} |
Si ensuite je veux pouvoir faire une allocation dynamique d'une variable dia_s, je met à disposition les fonctions "NomStruct_New" et une fonction "NomStruct_Delete".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| dia_s *Dia_New(void)
{
dia_s *new = NULL;
new = malloc(sizeof(*new));
if (!new) {
// Message erreur (possible d'utiliser perror (3) / strerror (3))
} else {
Dia_Constructor(&new);
}
return new;
}
void Dia_Delete(dia_s *self)
{
if (self) {
Dia_Destructor(self);
free(self);
}
} |
Le point que je veux mettre en avant, c'est que je n'ai pas utiliser goto dans Dia_New.
La fonction n'est absolument pas censé évoluer, c'est complétement ridicule d'utiliser goto dans cette situation (1 test avec 1 variable) et l'utilisation de goto complexifierais le code pour rien.
Par contre, si je devais faire une fonction prenant un chemin vers un fichier et parsant le fichier pour peupler le tableau dynamique, c'est plus probable que j'utiliserais goto (erreur ouverture fichier, erreur lecture fichier, erreur de format, erreur de données [int], données en overflow [int] ...).
Tiens, petit truc que j'aime bien faire avec mes structures :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| /* dia : dynamic int array */
typedef struct dia {
int *array;
size_t size; /* Array size */
size_t nbElement; /* Number of element in array */
} dia_s;
#define DIA_CONSTRUCTOR { \
.array = NULL, \
.size = 0, \
.nbElement = 0 \
}
void Dia_Constructor(dia_s *self)
{
dia_s clean = DIA_CONSTRUCTOR;
*self = clean;
} |
Ca me permet de pouvoir déclarer et initialiser une variable en même temps
4 |
0 |