goto
est presque universellement découragé. Est-ce que l'utilisation de cette déclaration en vaut la peine?
goto
programming-practices
Casebash
la source
la source
goto
est ce que le processeur fait en fin de compte, mais cela ne fonctionne pas bien avec ce que les humains ont besoin de comprendre et d'abstraire car il n'y a pas de marque sur l'extrémité cible. Comparez avec IntercalCOMEFROM
.goto
n'est pas requis. C'est juste la manière la plus rationnelle de les implémenter dans les langages impératifs, car c'est la chose la plus proche de la sémantique même de la transition d'état. Et sa destination peut être assez éloignée de la source, elle n'entravera pas la lisibilité. Mon exemple préféré d'un tel code est la mise en œuvre par DE Knuth du jeu Adventure.Réponses:
Cela a été discuté plusieurs fois sur Stack Overflow, et Chris Gillum a résumé les utilisations possibles de
goto
:Je dirais, comme beaucoup d'autres le diraient, que dans tous ces cas, l'utilisation de
goto
est utilisée comme un moyen de sortir d'un coin dans lequel on s'est codé et est généralement un symptôme de code qui pourrait être refactorisé.la source
finally
blocs dans les langages modernes, et le second est résolu par desbreak
s étiquetés . Cependant, si vous êtes coincé avec C,goto
c'est à peu près la seule façon de résoudre ces problèmes avec élégance.finally
n'est valide que dans ces conditions. Il existe des situations très rares, mais valables, où un goto est la voie à suivre.break 3
oubreak myLabel
etgoto myLabel
. Oh, c'est juste le mot-clé. Si vous utilisezbreak
,continue
ou un mot-clé similaire, vous utilisez en fait ungoto
(Si vous utilisez,for, while, foreach, do/loop
vous utilisez un goto conditionnel.)Les constructions de flux de contrôle de niveau supérieur ont tendance à correspondre aux concepts du domaine problématique. Un if / else est une décision basée sur une condition. Une boucle indique d'effectuer une action à plusieurs reprises. Même une déclaration de rupture dit "nous faisions cela à plusieurs reprises, mais maintenant nous devons arrêter".
Une instruction goto, d'autre part, tend à correspondre à un concept dans le programme en cours d'exécution, pas dans le domaine problématique. Il dit de continuer l'exécution à un point spécifié du programme . Quelqu'un qui lit le code doit déduire ce que cela signifie par rapport au domaine problématique.
Bien sûr, toutes les constructions de niveau supérieur peuvent être définies en termes de gotos et de branches conditionnelles simples. Cela ne signifie pas qu'ils ne sont que des gotos déguisés. Considérez-les comme des gotos restreints - et ce sont les restrictions qui les rendent utiles. Une instruction break est implémentée comme un saut à la fin de la boucle englobante, mais il vaut mieux la considérer comme opérant sur la boucle dans son ensemble.
Toutes choses étant égales par ailleurs, le code dont la structure reflète celle du domaine problématique a tendance à être plus facile à lire et à maintenir.
Il n'y a aucun cas où une instruction goto est absolument requise (il y a un théorème à cet effet), mais il y a des cas où cela peut être la moins mauvaise solution. Ces cas varient d'une langue à l'autre, selon les constructions de niveau supérieur prises en charge par la langue.
En C, par exemple, je pense qu'il y a trois scénarios de base où un goto est approprié.
D'un autre côté, une machine à états finis explicite peut également être implémentée avec une instruction switch dans une boucle. Cela présente l'avantage que chaque état commence au même endroit dans le code, ce qui peut être utile pour le débogage, par exemple.
L'utilisation principale d'un goto dans un langage raisonnablement moderne (celui qui prend en charge if / else et les boucles) est de simuler une construction de flux de contrôle qui manque dans le langage.
la source
goto
. Les SSSM sont souvent de bonnes structures à utiliser, car ils séparent l'état SM de la construction d'exécution, mais ils n'éliminent pas vraiment les "gotos".Cela dépend sûrement du langage de programmation. La principale raison
goto
a été controversée en raison de ses effets néfastes qui surviennent lorsque le compilateur vous permet de l'utiliser trop généreusement. Des problèmes peuvent survenir, par exemple, s'il vous permet d'utilisergoto
de telle manière que vous pouvez maintenant accéder à une variable non initialisée, ou pire, pour sauter dans une autre méthode et jouer avec la pile d'appels. Il devrait être de la responsabilité du compilateur de refuser le flux de contrôle absurde.Java a tenté de «résoudre» ce problème en l'interdisant
goto
entièrement. Cependant, Java vous permet d'utiliser à l'return
intérieur d'unfinally
bloc et donc d'avaler une exception par inadvertance. Le même problème est toujours là: le compilateur ne fait pas son boulot. La suppressiongoto
de la langue ne l'a pas corrigé.En C #,
goto
est aussi sûr quebreak
,continue
,try/catch/finally
etreturn
. Il ne vous permet pas d'utiliser des variables non initialisées, il ne vous permet pas de sortir d'un bloc finally, etc. Le compilateur se plaindra. C'est parce qu'il résout le vrai problème, qui est comme je l'ai dit le flux de contrôle absurde.goto
n'annule pas comme par magie l'analyse d'affectation définitive et d'autres vérifications raisonnables du compilateur.la source
goto
n'est pas mal? Si c'est le cas, c'est le cas pour tous les langages modernes couramment utilisés avec unegoto
construction, pas seulement C # ...Oui. Lorsque vos boucles sont imbriquées à plusieurs niveaux,
goto
c'est le seul moyen de sortir élégamment d'une boucle intérieure. L'autre option consiste à définir un indicateur et à sortir de chaque boucle si cet indicateur remplit une condition. C'est vraiment moche et assez sujet aux erreurs. Dans ces cas,goto
c'est tout simplement mieux.Bien sûr, la
break
déclaration étiquetée de Java fait la même chose, mais sans vous permettre de sauter à un point arbitraire dans le code, ce qui résout proprement le problème sans autoriser les choses qui font legoto
mal.la source
Do
boucle. Pourquoi? Parce que je peux changer la boucle qui a besoin d'une rupture profonde en uneDo
boucle et taperExit Do
et il n'y a pasGoTo
. Les boucles imbriquées se produisent tout le temps. Briser les piles se produit environ% du temps.La plupart du découragement vient d'une sorte de "religion" qui a été créée autour de Dieu Djikstra qui était convaincante au début des années 60 à propos de son pouvoir aveugle de:
Cela n'a plus rien à voir avec l'
goto
énoncé des langages modernes, dont l'existence est simplement due à soutenir la création de structures de code autres que celles fournies par le langage.En particulier, le premier point principal ci-dessus est plus autorisé et le second est nettoyé (si vous
goto
sortez d'un bloc, la pile est déroulée correctement et tous les destructeurs appropriés sont appelés)Vous pouvez vous référer à cette réponse pour avoir une idée de la façon dont même le code n'utilisant pas goto peut être illisible. Le problème ne vient pas de lui-même, mais de sa mauvaise utilisation.
Je peux écrire un programme entier sans utiliser
if
, justefor
. Bien sûr, ce ne sera pas bien lisible, un look maladroit et inutilement compliqué.Mais le problème n'est pas
for
. C'est moi.Des choses comme
break
,continue
,throw
,bool needed=true; while(needed) {...}
, etc. sont faisant remarquer plus de Masqueradegoto
pour échapper à l' écart des cimeterres des zélotes Djikstrarian, que -50 ans après l'invention de laguages- modernes veulent toujours leurs prisonniers. Ils ont oublié de quoi Djikstra parlait, ils ne se souviennent que du titre de sa note (GOTO considéré comme nuisible, et ce n'était même pas son nouveau titre: il a été modifié par l'éditeur) et blâmer et bash, bash et blâmer chaque contructure ayant ces 4 lettre placée dans l'ordre.Nous sommes en 2011: il est temps de comprendre que le
goto
fait de tenir compte de laGOTO
déclaration de Djikstra était convaincant.la source
break n
n'est pas disponible en C ++, doncgoto escape
, même s'ilescape
n'est pas nécessaire qu'il soit juste sorti de la boucle n-ple.Le goto impair ici ou là, tant qu'il est local à une fonction, nuit rarement de manière significative à la lisibilité. Il en profite souvent en attirant l'attention sur le fait qu'il se passe quelque chose d'inhabituel dans ce code qui nécessite l'utilisation d'une structure de contrôle quelque peu inhabituelle.
Si les gotos (locaux) nuisent considérablement à la lisibilité, cela signifie généralement que la fonction contenant le goto est devenue trop complexe.
Le dernier goto que j'ai mis dans un morceau de code C était de construire une paire de boucles de verrouillage. Il ne rentre pas dans la définition normale de l'utilisation «acceptable», mais la fonction est finalement devenue beaucoup plus petite et plus claire. Pour éviter le goto, il aurait fallu une violation particulièrement désordonnée de DRY.
la source
Je pense que toute cette question a consisté à aboyer le mauvais arbre.
GOTO en tant que tel ne me semble pas problématique, mais il s'agit plutôt très souvent d'un symptôme d'un véritable péché: le code spaghetti.
Si le GOTO provoque un croisement majeur des lignes de contrôle de flux, alors c'est mauvais, point final. S'il ne traverse aucune ligne de contrôle de débit, il est inoffensif. Dans la zone grise entre les deux, nous avons des choses comme les renflouements de boucle, il y a encore des langages qui n'ont pas ajouté de constructions qui couvrent tous les cas gris légitimes.
Le seul cas où je me suis retrouvé à l'utiliser effectivement depuis de nombreuses années est le cas de la boucle où le point de décision est au milieu de la boucle. Vous vous retrouvez avec un code en double, un drapeau ou un GOTO. Je trouve que la solution GOTO est la meilleure des trois. Il n'y a pas de croisement de lignes de contrôle de flux ici, c'est inoffensif.
la source
goto
s qui sautent dans une boucle (si la langue le permet; depuis l'autre cas, sauter hors de la boucle au milieu, est généralement trivial sansgoto
).goto
que crier LE FLUX DE CONTRÔLE ICI NE CONVIENT PAS AUX MODÈLES DE PROGRAMMATION STRUCTURÉS NORMAUX . Parce que les flux de contrôle qui correspondent à des modèles de programmation structurés sont plus faciles à raisonner que ceux qui ne le font pas, on devrait essayer d'utiliser ces modèles lorsque cela est possible; si le code correspond à de tels modèles, il ne faut pas crier que non. D'un autre côté, dans les cas où le code ne correspond pas vraiment à de tels modèles, il peut être préférable de le crier que de prétendre que le code convient quand il ne le fait pas vraiment.Oui, le goto peut être utilisé pour bénéficier de l'expérience du développeur: http://adamjonrichardson.com/2012/02/06/long-live-the-goto-statement/
Cependant, comme pour tout outil puissant (pointeurs, héritage multiple, etc.), il faut être discipliné en l'utilisant. L'exemple fourni dans le lien utilise PHP, ce qui limite l'utilisation de la construction goto à la même fonction / méthode et désactive la possibilité de sauter dans un nouveau bloc de contrôle (par exemple, boucle, instruction switch, etc.)
la source
Dépend de la langue. Il est encore largement utilisé dans la programmation Cobol, par exemple. J'ai également travaillé sur un appareil Barionet 50, dont le langage de programmation du micrologiciel est un ancien dialecte BASIC qui, bien sûr, vous oblige à utiliser Goto.
la source
Je dirais non. Si vous trouvez la nécessité d'utiliser GOTO, je parie qu'il est nécessaire de repenser le code.
la source
goto
peut être utile lors du portage du code assembleur hérité vers C. Dans un premier temps, une conversion instruction par instruction en C, engoto
remplacement de l'branch
instruction assembleur , peut permettre un portage très rapide.la source
Je dirais non. Ils doivent toujours être remplacés par un outil plus spécifique au problème que le goto est utilisé pour résoudre (sauf s'il n'est pas disponible dans votre langue). Par exemple, les instructions break et les exceptions résolvent les problèmes précédemment résolus de fuite de boucle et de gestion des erreurs.
la source
goto
sont généralement absentes de ces langues.goto
la chose la plus proche de la sémantique du domaine très problématique, tout le reste serait un sale hack.