79 votes

Des exemples de bonnes gotos en C ou C++

Dans ce fil, nous regardons des exemples de bonnes utilisations de l' goto en C ou C++. Elle est inspirée par une réponse qui, les gens ont voté parce qu'ils pensaient que je plaisantais.

Résumé (de l'étiquette a changé à partir de l'original à l'intention de faire encore plus clair):

infinite_loop:

    // code goes here

goto infinite_loop;

Pourquoi c'est mieux que les alternatives:

  • Il est spécifique. goto est le structure du langage, ce qui provoque une inconditionnel de la branche. Alternatives dépendent de l'aide de structures soutenir les branches conditionnelles, avec un dégénéré toujours vrai condition.
  • L'étiquette des documents à l'intention sans l'ajout de commentaires.
  • Le lecteur n'a pas à scanner le code intervenant pour le début de l' breaks (même si c'est encore possible pour une amorales hacker pour simuler continue avec un début goto).

Règles:

  • De prétendre que la gotophobes n'a pas gagner. Il est entendu que la ci-dessus ne peut pas être utilisée dans le code réel, parce que il va à l'encontre établi idiome.
  • Supposons que nous avons tous entendu parler de 'Goto considéré comme nocif" et de savoir que goto peut être utilisé pour écrire code spaghetti.
  • Si vous êtes en désaccord avec un exemple, de le critiquer sur le mérite technique seul ("Parce que les gens n'aiment pas goto " n'est pas une raison technique).

Voyons voir si nous pouvons en parler comme des adultes.

Modifier

Cette question semble maintenant terminé. Il a généré certains de haute qualité des réponses. Merci à tout le monde, surtout ceux qui ont pris ma petite boucle exemple au sérieux. Les plus sceptiques ont été concernés en l'absence de bloc de portée. @Quinmars souligné dans un commentaire, vous pouvez toujours mettre des accolades autour de la corps de boucle. Je note en passant que, for(;;) et while(true) ne vous donnent pas les accolades gratuitement soit (et en omettant entre eux peuvent provoquer des épineux de bugs). De toute façon, je ne vais pas perdre plus de de votre puissance de cerveau sur cette bagatelle - je peux vivre avec des inoffensifs et idiomatiques for(;;) et while(true) (tout aussi bien si je veux garder mon job).

Considérant les autres réponses, je vois que beaucoup de gens considèrent goto comme quelque chose que vous avez toujours réécrire une autre manière. Bien sûr, vous pouvez éviter une goto par l'introduction d'une boucle, un indicateur supplémentaire, une pile de imbriquée ifs, ou que ce soit, mais pourquoi ne pas envisager de s' goto est peut-être le meilleur outil pour le travail? Mettre une autre manière, quel laideur sont des gens prêts à endurer pour éviter d'utiliser un langage intégré fonction de son objet? De mon point de vue est que même l'ajout d'un indicateur est un prix trop élevé à payer. J'aime mes variables à représenter les choses dans le problème ou la solution de domaines. "Seulement pour éviter une goto' ne coupe pas.

Je vais accepter la première réponse qui a donné le C motif pour branchement à un nettoyage du bloc. L'OMI, ce qui rend l'argument le plus fort pour un goto de toutes les réponses, certainement si vous mesurez par les contorsions un hater a à faire pour l'éviter.

87voto

Greg Rogers Points 18119

Heres un truc que j'ai entendu parler de gens utilisent. Je ne l'ai jamais vu à l'état sauvage. Et il s'applique uniquement aux C parce que C++ a RAII pour ce faire plus idiomatique.

void foo()
{
    if (!doA())
        goto exit;
    if (!doB())
        goto cleanupA;
    if (!doC())
        goto cleanupB;

    /* everything has succeeded */
    return;

cleanupB:
    undoB();
cleanupA:
    undoA();
exit:
    return;
}

85voto

Paul Nathan Points 22910

Le classique de la nécessité de GOTO en C est comme suit

for ...
  for ...
    if(breakout_condition) 
      goto final;

final:

Il n'y a pas de façon simple de sortir de boucles imbriquées sans goto.

32voto

fizzer Points 8193

Voici mon exemple stupide, (à partir de Stevens APITUE) pour les appels système Unix qui peut être interrompu par un signal.

restart:
    if (system_call() == -1) {
        if (errno == EINTR) goto restart;

        // handle real errors
    }

L'alternative est un dégénéré de la boucle. Cette version se lit comme l'anglais "si l'appel système a été interrompu par un signal, redémarrer".

14voto

Mitch Wheat Points 169614

Si Duff de l'appareil n'a pas besoin d'un goto, alors vous non plus! ;)

void dsend(int count) {
    int n;
    if (!count) return;
    n = (count + 7) / 8;
    switch (count % 8) {
      case 0: do { puts("case 0");
      case 7:      puts("case 7");
      case 6:      puts("case 6");
      case 5:      puts("case 5");
      case 4:      puts("case 4");
      case 3:      puts("case 3");
      case 2:      puts("case 2");
      case 1:      puts("case 1");
                 } while (--n > 0);
    }
}

le code ci-dessus à partir de Wikipedia entrée.

14voto

zvrba Points 14028

Knuth a écrit un livre "programmation Structurée avec les instructions GOTO", vous pouvez l'obtenir par ex. à partir d' ici. Vous trouverez de nombreux exemples.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X