L'exemple de la programmation objet [...] alors l'intérêt d'un goto là dedans...
on est bien d'accord, le goto en C++, c nul. Par contre, en C, pour le traitement des erreurs, c'est très bien. Et là je te rejoins sur le côté exceptionnel des exceptions. Dans un parser qui effectue un certain nombre d'allocations dynamiques dans la même fonction, que doit-on faire pour le traitement des erreurs à chaque test.
const char *a,*b,*c,*d;
a = malloc(12);
if(a==NULL) return;
b = malloc(12);
if(b==NULL) { free(a); return; }
c = malloc(12);
if(c==NULL) { free(a); free(b); return; }
etc...
bref, c'est chiant à mourrir, et qui plus est on duplique le code de libérationde la mémoire. Alors tu peut aussi faire ça dans un do{...}while(0) et faire un break dès que tu as une erreur, mais je ne vois pas la vraie différence avec le goto.
je préfère de loin
const char *a=NULL,*b=NULL,*c=NULL,*d=NULL;
a = malloc(12);
if(a==NULL) goto fail;
b = malloc(12);
if(b==NULL) goto fail;
c = malloc(12);
if(c==NULL) goto fail; etc...
je trouve cela plus clair et plus lisible, je n'ai qu'un seul code de traitement d'erreur, ce qui est suffisant et réduit mon risque d'erreur. C'est de l'émulation d'exceptions, bornée dans le scope de la fonction courante, et moi je dis que c'est bien!
qui fait de la programmation par aspect
en "C" ? mouarf! (mettons nous bien d'accord, je parle du goto en "C", rien de plus).
Ah bon tu remplacent le mot break/continue/return par un goto et tu comprends mieux ?
for(int i=0; i<347; ++i) {
do{
while(!f(i)) {
if g() break;
}
}
while(h());
if (g()) continue;
}
pour moi, ceci est illisible. le code étant compact, ça reste comphréensible, mais bien dilué, c'est affreux. Reste que c'est vrai, que l'insertion d'un goto ne rendrait pas les choses plus claires, quoi que...
break/continue/return sont des cas particulier de goto, ont une sémantique et une utilisation précise qui fait que tout le monde les comprend, notamment le compilateur
Que le compilateur comprenne, ca me parait être la moindre des choses. L'écrivain du code aussi. Le relecteur, je n'en suis pas aussi convaincu que toi. C'est pourquoi, dans la mesure du possible, je n'écrit _jamais_ du code comme cela. Les 'break' et 'continue' sont des nids à ennuis quand on travaille à plusieurs sur le même code.
alors je suis d'accord, il ne faut pas faire n'importe quoi avec le 'goto'. En dehors du traitement des erreurs, je n'en vois pas l'utilité. Mais ce cas à lui tout seul justifie amplement son utilisation à mes yeux. Alors entendre dire tout le temps qu'un programme qui utilise un goto est un programme mal conçu, c'est des conneries. C'est largement pire d'imbriquer 4 boucles for/do/while avec des break et/ou des continue.
PS:
le conseil de linuxfr est :"si vous souhaitez taper du code, n'utilisez pas ce format. [HTML]". => il faut utiliser quoi?
[^] # Re: Hmm :/
Posté par SoWhat . En réponse au journal Entretient du noyau Linux. Évalué à 2.
on est bien d'accord, le goto en C++, c nul. Par contre, en C, pour le traitement des erreurs, c'est très bien. Et là je te rejoins sur le côté exceptionnel des exceptions. Dans un parser qui effectue un certain nombre d'allocations dynamiques dans la même fonction, que doit-on faire pour le traitement des erreurs à chaque test.
const char *a,*b,*c,*d;
a = malloc(12);
if(a==NULL) return;
b = malloc(12);
if(b==NULL) { free(a); return; }
c = malloc(12);
if(c==NULL) { free(a); free(b); return; }
etc...
bref, c'est chiant à mourrir, et qui plus est on duplique le code de libérationde la mémoire. Alors tu peut aussi faire ça dans un do{...}while(0) et faire un break dès que tu as une erreur, mais je ne vois pas la vraie différence avec le goto.
je préfère de loin
const char *a=NULL,*b=NULL,*c=NULL,*d=NULL;
a = malloc(12);
if(a==NULL) goto fail;
b = malloc(12);
if(b==NULL) goto fail;
c = malloc(12);
if(c==NULL) goto fail;
etc...
/* retour normal */
return 0;
fail:
if(a!=NULL) free(a);
if(b!=NULL) free(b);
if(c!=NULL) free(c);
etc...
return -1;
je trouve cela plus clair et plus lisible, je n'ai qu'un seul code de traitement d'erreur, ce qui est suffisant et réduit mon risque d'erreur. C'est de l'émulation d'exceptions, bornée dans le scope de la fonction courante, et moi je dis que c'est bien!
en "C" ? mouarf! (mettons nous bien d'accord, je parle du goto en "C", rien de plus).
for(int i=0; i<347; ++i) {
do{
while(!f(i)) {
if g() break;
}
}
while(h());
if (g()) continue;
}
pour moi, ceci est illisible. le code étant compact, ça reste comphréensible, mais bien dilué, c'est affreux. Reste que c'est vrai, que l'insertion d'un goto ne rendrait pas les choses plus claires, quoi que...
Que le compilateur comprenne, ca me parait être la moindre des choses. L'écrivain du code aussi. Le relecteur, je n'en suis pas aussi convaincu que toi. C'est pourquoi, dans la mesure du possible, je n'écrit _jamais_ du code comme cela. Les 'break' et 'continue' sont des nids à ennuis quand on travaille à plusieurs sur le même code.
alors je suis d'accord, il ne faut pas faire n'importe quoi avec le 'goto'. En dehors du traitement des erreurs, je n'en vois pas l'utilité. Mais ce cas à lui tout seul justifie amplement son utilisation à mes yeux. Alors entendre dire tout le temps qu'un programme qui utilise un goto est un programme mal conçu, c'est des conneries. C'est largement pire d'imbriquer 4 boucles for/do/while avec des break et/ou des continue.
PS:
le conseil de linuxfr est :"si vous souhaitez taper du code, n'utilisez pas ce format. [HTML]". => il faut utiliser quoi?