Developpez.com

Plus de 14 000 cours et tutoriels en informatique professionnelle à consulter, à télécharger ou à visionner en vidéo.

Goto : une instruction pas comme les autres ?
Le débat autour de l'instruction refait surface suite au « Goto fail » d'iOS et de GnuTLS

Le , par Arsene Newman, Expert éminent sénior
Suite à la découverte récente de bugs à la fois sous Linux et sous iOS/OS X, tous les deux dus à une utilisation de l’instruction Goto du langage C, la question de l’utilisation de cette instruction refait surface.

Goto est une instruction héritée des premiers langages informatiques, époque où certaines instructions très connues actuellement n’existaient pas, comme les boucles et les structures de contrôle. Néanmoins, même à l’âge moderne de l’informatique et après avoir été décriée par plusieurs informaticiens de renom à l’instar de Djikistra, cette instruction est encore utilisée et cela même au sein des géants de l’informatique comme Apple ; à titre d’exemple la recherche du mot clé Goto sur un portail tel que GitHub débouche sur des millions de résultats.

Alors dans quel cas cette instruction est encore utilisée ? Parmi les cas de figure évoqués existent la sortie d’une boucle imbriquée ce qui épargne le recours à plusieurs break, l’amélioration de la lisibilité du code et le traitement des erreurs ou encore l’optimisation manuelle du code pour améliorer les performances.

Toutefois, alors qu’une utilisation parcimonieuse dans les deux premiers cas semble correcte, cela s’avère incorrect pour le dernier cas, selon Jeff Law et Jason Merril, tous les deux ingénieurs chez Red Hat et membres du comité du compilateur GCC. En effet ils expliquent que l’optimisation manuelle du code n’est plus à l’ordre du jour car les compilateurs modernes sont suffisamment développés pour se charger gracieusement de cette tâche, en transformant le code en entrée en une série de blocs de base et en se reposant sur l’utilisation d’un graphe de flot de contrôle (GFC). Résultat des courses aucune distinction entre un code bien structuré et un code en spaghetti (qui résulte d’une addiction au goto).

Autre argument en faveur de cette thèse, l’article du célèbre Donald Knuth sur le sujet à savoir « Structured Programming with Go To Statements », où il explique qu’une optimisation prématurée du code ne peut déboucher que sur une utilisation malsaine de Goto.

Au final, la recommandation de l’utilisation du Goto n’est toujours pas à l’ordre du jour, mais cette instruction héritée des premiers âges de l’informatique garde encore sa place dans des cas précis où certains langages, à l’image du langage C, affichent des manques et des carences, ce qui ne cadre pas avec un quelconque souci d’optimisation manuelle du code.

Source : billet de Larry Seltzer

Et vous ?

Qu’en pensez-vous ?


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de Bktero Bktero - Modérateur https://www.developpez.com
le 14/03/2014 à 8:50
On va sérieusement relancer un débat sur goto là ?

J'ai utilisé goto pour la première fois avant-hier dans un code avec pas mal de if imbriqués. Un nouveau cas s'est présenté et je voulais sauter directement à la gestion d'erreur. J'ai voulu mettre un breakpoint à cet endroit et mon IDE m'a envoyé promener. J'ai alors réécris ma boucle proprement. Et je ne compte pas retenter ma chance. Il y a eu des milliers de débats sur goto dans le monde. La plupart de temps avec des gens qui ne s'en sont jamais servi. goto peut avoir ses intérêts dans certains cas qui sont assez bien identifiés. Mais le fait que quasiment personne ne s'en sert montre qu'on peut presque toujours faire autrement. L'optimisation manuelle du code ne concerne même pas goto en particulier. Le compilateur est là pour optimiser du code qui doit être bien pensé. "Premature optimization is the root of all evil" est valable pour toute optimisation, pas uniquement goto.

.....

Mince, j'avais pas tilté qu'on était vendredi

EDIT : je viens de regarder le code sur drdobbs.com.... L'erreur vient aussi (surtout !) du fait qu'il n'y a pas de crochets accolades autour des if. DES ***** DE CROCHETS ACCOLADES !
Avatar de Arsene Newman Arsene Newman - Expert éminent sénior https://www.developpez.com
le 14/03/2014 à 10:55
Citation Envoyé par Bktero  Voir le message
On va sérieusement relancer un débat sur goto là ?

Il s'agit surtout de souligner un mauvais cas d'utilisation, à savoir pretexter l'utilisation du Goto par souci d'optimisation

Citation Envoyé par Bktero  Voir le message
EDIT : je viens de regarder le code sur drdobbs.com.... L'erreur vient aussi (surtout !) qu'il n'y a pas de crochets autour des if. DES ***** DE CROCHETS !

Effectivement oui
Avatar de Obsidian Obsidian - Responsable Modération https://www.developpez.com
le 14/03/2014 à 11:32
Citation Envoyé par Arsene Newman  Voir le message
Suite à la découverte récente de bugs à la fois sous Linux et sous iOS/OS X, tous les deux dus à une utilisation de l’instruction Goto du langage C, la question de l’utilisation de cette instruction refait surface.

Ce n'est pas lié au goto, mais au fait qu'une ligne s'est trouvée dupliquée. 'faudrait voir à ne pas troller plus encore qu'on le fait déjà à ce sujet. Il aurait bien pu se passer la même chose avec un point-virgule mal placé, ce qui est assez fréquent en C.

Goto est une instruction héritée des premiers langages informatiques, époque où certaines instructions très connues actuellement n’existaient pas, comme les boucles et les structures de contrôles. Néanmoins, même à l’âge moderne de l’informatique et après avoir été décrié par plusieurs informaticiens de renom à l’instar de Djikistra, cette instruction est encore utilisée et cela même au sein des géants de l’informatique comme Apple, à titre d’exemple la recherche du mot clé Goto sur un portail tel que GitHub débouche sur des millions de résultats.

Paradoxalement, c'est en BASIC 512 et en GW BASIC que j'ai rencontré les pires incompatibilités avec, parce que le langage était interprété et que la fin d'une boucle DO…LOOP ou FOR…NEXT était matérialisée par une instruction, laquelle pouvait en plus être éventuellement soumise à un IF. Les structures de boucles en cours étaient alors stockées dans la pile et faire un goto ne nettoyait donc pas cette pile. Ça restait tout-à-fait légal, d'ailleurs, puisque rien ne nous interdisait de re-sauter vers l'intérieur de la boucle, même si tout cela était sale. En C, ça l'est moins justement parce que les bornes sont définies à la compilation et que le tout est résolu en une série de JMP (donc des gotos) une fois compilé.

Alors dans quel cas cette instruction est encore utilisée ? Parmi les cas de figure évoqués existent la sortie d’une boucle imbriquée ce qui épargne le recours à plusieurs break, l’amélioration de la lisibilité du code et le traitement des erreurs ou encore l’optimisation manuelle du code pour améliorer les performances.

Outre ceux cités, j'ai personnellement deux cas en tête :

1. La possibilité de sauter dans une boucle pour la faire démarrer ailleurs qu'au début, ce qui permet de gérer efficacement les cas du style « 1 + le reste » très utilisés en informatique et dans les séries mathématiques. Par exemple, pour écrire une suite de chiffres séparés par des tirets :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
x=1; goto debut; 
while (x<=5) 
{ 
    putchar ('-'); 
    debut: 
    printf ("%d",x); 
    x++; 
}
… et qui donne « 1-2-3-4-5 ». Ceci nous permet d'éviter un « if() » au sein de la boucle, évalué à chaque tour simplement pour traiter le premier cas. Je me suis rendu compte a posteriori que c'était l'exemple donné dans la norme pour illustrer goto.

On remarque que ça pourrait tout-à-fait être un modèle de boucle à part entière : de même qu'il existe « continue » en C pour provoquer le saut immédiat vers la fin de la boucle et lui faire faire une itération, on pourrait tout-à-fait imaginer un mot-clé « start » servant à faire cela.

2. Les automates finis à états. Le goto est par nature l'âme d'un AFD, puisqu'il s'agit de sauter d'un état prédéterminé à un autre. Si le cheminement du traitement est déterminé à l'avance, il est tout-à-fait possible d'écrire :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
etat1: 
    traitement1(); 
    if (condition) goto etat2; 
    if (condition) goto etat3; 
    if (condition) goto etat5; 
    goto etat6; 
 
etat2: 
    traitement2(); 
    if (condition) goto etat6; 
    if (condition) goto etat4; 
    if (condition) goto etat1; 
    goto etat2; 
 
…
… dans de telles conditions, on va avoir tendance à écrire un switch() et à stocker l'état en cours dans une variable, ce qui transpose inutilement au runtime ce qui est statique à la base.

Ce que l'on reproche au goto, donc, c'est surtout d'être généralement incompatible avec la programmation structurée. Mais ça, c'est un paradigme qui doit être pensé par le programmeur avant tout. De la même façon qu'il est possible d'avoir une approche orientée objet en C même si le langage n'est pas spécialement conçu pour cela au départ, il est possible d'écrire un programme propre avec des gotos si le programmeur le souhaite. L'ennui est qu'il est généralement impossible de le faire admettre à son entourage direct et qu'en entreprise, il est plus facile d'écrire du code sale mais « orthodoxe » plutôt qu'avoir à justifier son goto.

Toutefois alors qu’une utilisation parcimonieuse dans les deux premiers cas semble correcte, cela ne s’avère pas correcte pour le dernier cas selon Jeff Law et Jason Merril tous les deux ingénieurs chez Red Hat et membre du comité du compilateur GCC, en effet ils expliquent que l’optimisation manuelle du code n’est plus à l’ordre du jour car les compilateurs modernes sont suffisamment développés pour se charger gracieusement de cette tâche, en transformant le code en entrée en une série de blocs de base et en se reposant sur l’utilisation d’un graphe de flot de contrôle (GFC), résultat des courses aucune distinction entre un code bien structuré et un code en spaghetti (qui résulte d’une addiction au goto).

Il faudrait commencer par arrêter d'associer systématiquement goto et code spaghetti. D'abord parce qu'à la longue, ça devient pénible, ensuite et surtout parce que rien n'empêche un programmeur d'écrire du code spaghetti sans goto. Et précisément, une grande maladie, contemporaine cette fois, consiste à éliminer tous les gotos et les remplacer par n'importe quoi d'autre, sans se soucier de savoir si c'est réellement plus efficace (même au niveau global) et surtout si ce n'est pas pire.

Ensuite, au niveau du compilateur, c'est vrai mais dans une certaine mesure également. Il est vrai que les compilateurs sont devenus particulièrement performants mais le fait est qu'on leur prête souvent des pouvoirs magiques et que les gens qui se penchent réellement sur la qualité du code produit sont bien peu nombreux.

Au final, la recommandation de l’utilisation du Goto n’est toujours pas à l’ordre du jour mais cette instruction héritée des premiers âges de l’informatique garde encore sa place dans des cas précis où certains langages à l’image du langage C affichent des manques et des carences, ce qui ne cadre pas avec un quelconque souci d’optimisation manuelle du code.

goto, c'est comme l'utilisateur root sous Unix : c'est l'instruction omni-potente. Il faut juste veiller à ne pas l'utiliser pour se sortir d'une impasse (et c'est surtout ça qu'il faut surveiller à mon avis) mais ça permet d'implémenter facilement ce qui n'a pas été prévu au départ.

Citation Envoyé par Bktero  Voir le message
Mais le fait que quasiment personne ne s'en sert montre qu'on peut presque toujours faire autrement.

Un vrai débat de fond, voire un sujet d'études scientifique, serait d'auditer un grand nombre de programmes chez les codeurs de tous niveaux et vérifier si, à chaque fois, la solution alternative adoptée est réellement meilleure. Mais ça…
Avatar de valkirys valkirys - Membre expérimenté https://www.developpez.com
le 14/03/2014 à 12:29
Citation Envoyé par Bktero  Voir le message
goto peut avoir ses intérêts dans certains cas qui sont assez bien identifiés. Mais le fait que quasiment personne ne s'en sert montre qu'on peut presque toujours faire autrement. L'optimisation manuelle du code ne concerne même pas goto en particulier.

Même un if then else sera compilé avec des goto, le but premier des langages ( structurés ) est de simplifier le code source en supprimant les goto qui pique les yeux...

Citation Envoyé par Obsidian  Voir le message
Code : Sélectionner tout
1
2
3
4
5
6
7
8
x=1; goto debut; 
while (x<5) 
{ 
    putchar ('-'); 
    debut: 
    printf ("%d",x); 
    x++; 
}
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
etat1: 
    traitement1(); 
    if (condition) goto etat2; 
    if (condition) goto etat3; 
    if (condition) goto etat5; 
    goto etat6; 
 
etat2: 
    traitement2(); 
    if (condition) goto etat6; 
    if (condition) goto etat4; 
    if (condition) goto etat1; 
    goto etat2; 
 
…

Ok pour le deuxième mais le premier se réécrit :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
printf ("%d",1); 
x=2; 
while (x<5) 
{ 
    putchar ('-'); 
    printf ("%d",x); 
    x++; 
}
je ne vois pas l’intérêt du goto.
Avatar de Washmid Washmid - Membre actif https://www.developpez.com
le 14/03/2014 à 12:34
Mes souvenirs en C sont un peu rouillés mais un truc du genre revient un peu au même que l'exemple en 1 :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
x=1; 
for(;;) 
{ 
    printf ("%d",x); 
    x++; 
    if (x==5) break; 
    putchar ('-'); 
}
EDIT : arf, valkirys, plus rapide que moi et sans break mais avec une ligne copiée-collée ^^

Bref, histoire d'illustrer la possibilité d'alternatives.

Pour les sorties de boucles, java propose une instruction "break nom_label" qui permet de sauter en dehors de la boucle préfixée par "nom_label:".

C'est n'est que mon avis, mais même ce break-goto devrait être remplacé par une méthode qui contient un return dans la boucle, car il est souvent la manifestation d'une méthode trop complexe qui mériterait être découpée.
Avatar de valkirys valkirys - Membre expérimenté https://www.developpez.com
le 14/03/2014 à 12:43
Citation Envoyé par Washmid  Voir le message
EDIT : arf, valkirys, plus rapide que moi et sans break mais avec une ligne copiée-collée ^^

Je trouve que ça colle bien à l'algorithme, un cas d'initialisation avant une boucle, non?

Citation Envoyé par Washmid
C'est n'est que mon avis, mais même ce break-goto devrait être remplacé par une méthode qui contient un return dans la boucle, car il est souvent la manifestation d'une méthode trop complexe qui mériterait être découpée.

ça donne pourtant un code clair et je vois pas l'intérêt d'introduire une fonction juste pour ça!

Par exemple, tester le contenue d'une "matrice" à N dimension implique N boucles avec un break si on a trouvé ce que l'on cherche, rien de compliqué a priori :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
search: { 
    for (Type type : types) { 
        for (Type t : types2) { 
            if (some condition) { 
                // Do something and break... 
                break search; 
            } 
        } 
    } 
}
(en java copier-coller de stackoverflow, c'est mal je sais )
Avatar de Obsidian Obsidian - Responsable Modération https://www.developpez.com
le 14/03/2014 à 12:56
Citation Envoyé par valkirys  Voir le message
Même un if then else sera compilé avec des goto, le but premier des langages ( structurés ) est de simplifier le code source en supprimant les goto qui pique les yeux...

La vraie question est : pourquoi ça te pique les yeux (à part le fait que c'est ce que l'on t'a toujours dit) ? Les réponses existent et elles sont à la base de ce débat, mais elles sont discutables en fonction de la situation et surtout, plus personne ne se pose cette question, même au départ.

Et c'est bien le problème : l'objectif des codeurs n'est plus d'écrire le code le propre possible en fonction du contexte mais bien d'éviter les goto par principe.

Ok pour le deuxième mais le premier se réécrit :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
printf ("%d",1); 
x=2; 
while (x<5) 
{ 
    putchar ('-'); 
    printf ("%d",x); 
    x++; 
}
je ne vois pas l’intérêt du goto.

Justement pour éviter d'avoir à écrire deux fois la même chose, uniquement pour prendre en compte le cas initial !

Dans cet exemple, tu saisis deux fois « printf() » mais tu n'établis aucune relation logique entre les deux : le compilateur n'a aucun moyen de savoir que ton premier printf() est en fait censé faire partie de la même boucle, ce qui casse complètement le principe-même de la programmation structurée. Ensuite, même si ce n'était pas nécessaire, tu as changé la condition initiale (x=2 et plus x=1) et quitte à écrire printf("%d",1);, tu aurais pu directement écrire printf("1");. Donc, des erreurs en cascade induites par la volonté de se priver du goto et qui, au final, rendent le code moins bon qu'au départ.

Ensuite, dans le cas présent, il n'y a qu'une seule instruction. Que se passerait-il si tu devais sauter les cinquante premières instructions d'une boucle qui en compte cent ? Pour adopter le modèle que tu nous présentes, tu serais obligé de déclarer une fonction pour les appeler facilement avant puis dans la boucle. Et si tu retrouves le même cas de figure trente fois dans ton programme, tu dois déclarer trente fonctions locales. C'est idiot.

C'est également plus pénible pour le développeur : même s'il reconnaît ce que tu es en train de faire, il ne peut pas savoir s'il y a bien une liaison implicite entre tes deux printf. Ça devient critique lorsque tu fais la maintenance d'un grand programme : lorsque tu en vient à modifier ce printf pour le mettre à jour ou le remplacer par autre chose, tu introduis automatiquement un bug si tu ne penses pas à traiter l'autre.

Il est intéressant, lorsque l'on développe du logiciel, d'essayer de transposer cela au reste de l'industrie et, en particulier, de penser à la manière dont on réaliserait la fonction de façon mécanique plutôt que logicielle : dans le cas présent, si je veux imprimer sur une feuille une suite de motifs séparés par des tirets, il me suffit de construire un simple rouleau d'imprimerie et de le « déphaser » de manière à ce qu'il commence par le motif plutôt que par le tiret. La solution que tu nous proposes consisterait, elle, à mettre en place une machine spéciale dédiée pour imprimer le premier motif uniquement avant de faire passer normalement la feuille dans le rouleau.

Tout cela pour éviter un goto qui aurait eu tout-à-fait sa place ici.

C'est intéressant parce qu'en général, on en arrive à dire « de toutes façons le compilateur va optimiser tout cela ». Personne ne nous le garantit, d'une part, et cela revient à dire que le vrai travail est en fait mené par les personnes qui ont conçu le compilateur. Et même alors, le compilateur sera à même de faire cette optimisation que s'il est capable de reconnaître le modèle. Il faut donc que celui-ci soit défini au départ et fasse partie des motifs qui lui ont été enseignés. En toute rigueur, c'est surtout ce travail que le programmeur devrait faire, et utiliser les goto si le langage ne propose pas de lui-même ce modèle.

Citation Envoyé par Washmid  Voir le message
Mes souvenirs en C sont un peu rouillés mais un truc du genre revient un peu au même que l'exemple en 1 :
EDIT : arf, valkirys, plus rapide que moi et sans break mais avec une ligne copiée-collée ^^

C'était justement le problème de départ : éviter de se trimballer un « if » évalué à chaque itération alors qu'il n'est là que pour tester le premier cas.
Avatar de valkirys valkirys - Membre expérimenté https://www.developpez.com
le 14/03/2014 à 13:24
Citation Envoyé par Obsidian  Voir le message
La vraie question est : pourquoi ça te pique les yeux (à part le fait que c'est ce que l'on t'a toujours dit) ? Les réponses existent et elles sont à la base de ce débat, mais elles sont discutables en fonction de la situation et surtout, plus personne ne se pose cette question, même au départ.

On ne m'a rien dit!
J'ai appris l'assembleur seul et n'ai pas fait d'études en informatique.
Je vois la différence entre de la programmation objet/structuré et des jump en asm ( je suis allergique au fonctionnel).

Citation Envoyé par Obsidian
Justement pour éviter d'avoir à écrire deux fois la même chose, uniquement pour prendre en compte le cas initial !

Dans cet exemple, tu saisis deux fois « printf() » mais tu n'établis aucune relation logique entre les deux : le compilateur n'a aucun moyen de savoir que ton premier printf() est en fait censé faire partie de la même boucle, ce qui casse complètement le principe-même de la programmation structurée. Ensuite, même si ce n'était pas nécessaire, tu as changé la condition initiale (x=2 et plus x=1) et quitte à écrire printf("%d",1);, tu aurais pu directement écrire printf("1");. Donc, des erreurs en cascade induites par la volonté de se priver du goto et qui, au final, rendent le code moins bon qu'au départ.

Ensuite, dans le cas présent, il n'y a qu'une seule instruction. Que se passerait-il si tu devais sauter les cinquante premières instructions d'une boucle qui en compte cent ? Pour adopter le modèle que tu nous présentes, tu serais obligé de déclarer une fonction pour les appeler facilement avant puis dans la boucle. Et si tu retrouves le même cas de figure trente fois dans ton programme, tu dois déclarer trente fonctions locales. C'est idiot.

Idot? Je comprends bien à la lecture des derniers paragraphes votre façon de faire très mécanique, mais je trouve normal de découper un algorithme en une phase d'initialisation+ traitement des cas puis une partie automatique (boucle) c'est plus clair.
Et si il faut introduire des fonctions alors c'est d'accord pour moi.
( pour le printf("%d",1);, on est d'accord c'est un exemple écrit vite fait )

Citation Envoyé par Obsidian
Ça devient critique lorsque tu fais la maintenance d'un grand programme : lorsque tu en vient à modifier ce printf pour le mettre à jour ou le remplacer par autre chose, tu introduis automatiquement un bug si tu ne penses pas à traiter l'autre.

Il manque des commentaires expliquant que algorithmes à deux partis inutilisation et boucle. Et bien sûr il ne faudrait pas des 5 codé en dur...

Citation Envoyé par Obsidian
Il est intéressant, lorsque l'on développe du logiciel, d'essayer de transposer cela au reste de l'industrie et, en particulier, de penser à la manière dont on réaliserait la fonction de façon mécanique plutôt que logicielle : dans le cas présent, si je veux imprimer sur une feuille une suite de motifs séparés par des tirets, il me suffit de construire un simple rouleau d'imprimerie et de le « déphaser » de manière à ce qu'il commence par le motif plutôt que par le tiret. La solution que tu nous proposes consisterait, elle, à mettre en place une machine spéciale dédiée pour imprimer le premier motif uniquement avant de faire passer normalement la feuille dans le rouleau.

Intéressant mais je ne pense pas de cette manière, avec un langage type C ( pas fait d'assembleur depuis des années ) et je préfère la mienne ( initialisation, cas généraux ).

Citation Envoyé par Obsidian
Et c'est bien le problème : l'objectif des codeurs n'est plus d'écrire le code le propre possible en fonction du contexte mais bien d'éviter les goto par principe.

J'évite les goto ( sauf boucles imbriqués ) par principe mais pas pour ces raisons là.
Avatar de azias azias - Membre éclairé https://www.developpez.com
le 14/03/2014 à 13:41
Heureusement il y a toujours une actu sur developpez.com pour nous rappeler qu'on est vendredi.

Je crois bien que la dernière fois que j'ai utilisé une instruction goto c'était dans un programme basic, il doit y avoir une vingtaine d'années... je n'aurai pas mis ma main à couper sur le fait que les goto soient encore utilisés. Mais heureusement on n'a pas besoin des goto pour mettre plein de bugs dans les logiciels.

Vu comment sont actuellement développés les logiciels, je pense que les développeurs feraient mieux de chercher à optimiser l'utilisation mémoire plutôt que de perdre du temps à faire des goto.

Mais de là dire que les compilateurs actuels sont capables de faire de l’optimisation poussée automatiquement... je considère le C comme un langage relativement bas niveau dans le sens où le développeur s'attend à ce que le résultat de la compilation reste sassez proche du code source. Même si le C permet de faire des des choses plus complexe, je pense que quand on veut réellement faire de la programmation structurée et/ou abstraite on se dirige vers d'autres langages en utilisant les paradigmes de programmation qui leurs sont liés.

Par exemple un goto dans du C ne me choque pas car je m'attend à y lire de la programmation bas niveau, alors que dans du C++ ça m'interpellerait plus car je m'attend à y lire de la programmation objet de relativement haut niveau. Ce qui devient un compliqué et qui sera source d'erreurs c'est quand on veut mélanger le bas et le haut niveau.
Avatar de Obsidian Obsidian - Responsable Modération https://www.developpez.com
le 14/03/2014 à 14:03
Avant tout : je m'aperçois en me relisant que mon ton était peut-être un peu sec. Mes excuses à ce que j'aurais pu blesser, ce n'était pas intentionnel. Nous sommes bien en train de disserter sur le fond et rien d'autre.

Citation Envoyé par valkirys  Voir le message
OnIdot? Je comprends bien à la lecture des derniers paragraphes votre façon de faire très mécanique, mais je trouve normal de découper un algorithme en une phase d'initialisation+ traitement des cas puis une partie automatique (boucle) c'est plus clair.

Oui mais justement : le premier tour de boucle ne constitue pas une phase d'initialisation. C'est la même que celle des autres tours et l'une et l'autre doivent être modifiées en même temps si c'est nécessaire.

Et si il faut introduire des fonctions alors c'est d'accord pour moi.

En quoi — dans le cas présent — est-ce plus propre qu'un goto ?

( pour le printf("%d",1);, on est d'accord c'est un exemple écrit vite fait )

On est bien d'accord et c'est bien comme cela que je l'ai vu aussi : cela dit, c'est révélateur d'un problème assez fréquent : introduire des horreurs, volontairement ou non, pour corriger des choses qui n'ont pas besoin de l'être. C'est très fréquent en développement logiciel.

Il manque des commentaires expliquant que algorithmes à deux partis inutilisation et boucle. Et bien sûr il ne faudrait pas des 5 codé en dur...

Les commentaires sont un autre débat mais là encore, le problème de fond est différent : il s'agit bien d'un modèle de boucle à part entière et pas d'une initialisation préalable. Dans le cas du rouleau d'imprimerie, l'initialisation consisterait justement à placer le rouleau dans la bonne position avant de lancer la machine. Pas à imprimer le motif.

J'évite les goto ( sauf boucles imbriqués ) par principe mais pas pour ces raisons là.

Justement : la sortie d'une boucle imbriquée avec goto, ça se pratique parce qu'il n'existe pas de « break n ». On en revient à ce que l'on disait : on définit un modèle clair au départ et on l'implémente avec des gotos quand le langage ne le propose pas lui-même.

Maintenant, comme on l'a dit également, la sortie de boucle est un modèle qui marche très bien en C mais qui n'est pas du tout universel et qui pose problème justement avec les langages interprétés, à commencer par le BASIC où le goto, s'il n'en est pas carrément issu, est censé être roi.
Offres d'emploi IT
RESPONSABLE WEB ANALYTICS F/H
VACALIANS GROUP - Languedoc Roussillon - SETE (34)
Développeur WEB PHP F/H
VACALIANS GROUP - Languedoc Roussillon - SETE (34)
Développeur Web FULL-STACK
VACALIANS GROUP - Languedoc Roussillon - SETE (34)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique Accueil