Bienvenue sur PEBKAC.fr, le site qui recense les anecdotes où l’on se moque des utilisateurs ne maîtrisant pas l’outil informatique. PEBKAC est un acronyme signifiant « Problem Exists Between Keyboard And Chair ».
Le problème se situe entre la chaise et le clavier : soumettez vos histoires, donnez votre avis !
Ce site n'est pas le site original pebkac.fr. Je publie ici la liste des PEBKAC que j'ai pu sauvegarder avant que le site original ne soit mis hors ligne.
J'ai tendance à considérer qu'en langage C et dans les langages dérivés, il ne faut pas utiliser l'instruction « goto », sauf peut-être dans des contextes très particuliers, et encore.

Quoi qu'il en soit, un jour, je suis tombé sur le projet universitaire en C d'un stagiaire. Le début, classique, consistait en un menu dans la console avec un chiffre à entrer pour sélectionner l'action. Pour une raison quelconque, mon stagiaire avait décidé de ne pas entrer un chiffre comme choix, mais une lettre, et une lettre majuscule ou minuscule devait représenter le même choix.

Le main contenait donc un switch géant, du style :

switch (choix)
{
  case 'a' :
    // action a
    goto default;

  case 'A' :
    goto case 'a';

  default : 
    break;
}

Et apparemment, c'était son professeur qui lui avait indiqué « la meilleure manière de gérer son menu ». PEBKAC.
PEBKAC #7555 proposé par Raizarachi le 13/04/2013 | 18 commentaires | 👍🏽 👎🏽 +161
Que fait goto et pourquoi c'est le mal ?
Commentaire #88785 écrit par qwerty le 13/04/2013 à 09h52 | 👍🏽 👎🏽
ca fait sauter a un label particulier (ou visiblement ici a un case). le problème de faire ca c'est que très souvent ca casse la lisibilité. par exemple ici si l'utilisateur entre "A" ca va rentrer dans se second case, le goto case envoyer vers le premier case qui lui même fait la tambouille pour gérer la touche puis redirige vers le cas par défaut du switch.

tu sens l'imbroglio arriver? maintenant imagine le même genre de bordel mais avec un programme de 200 lignes avec des goto partout.


Je pense que le goto est une relique d'un temps ou il n'existait pas les structure de contrôle comme on en a maintenant.

EDIT : wikipedia dit :

L'instruction goto, directement héritée des instructions de saut des langages machines, était nécessaire dans les langages primitifs (Fortran pré-90, BASIC) comme instruction de base permettant de réaliser des boucles et autres structures de contrôles.

Depuis la révolution de la programmation structurée des années 1970, l'instruction goto n'est plus guère appréciée des programmeurs modernes, car elle rend souvent les programmes plus difficiles à comprendre et à maintenir (on parle dans ce cas de programmation spaghetti). On utilise plus généralement des structures comme les sauts conditionnels (if .. then .. else ..) ou les boucles (for, while, etc.) qui font partie intégrante de tous les langages de programmation impératifs modernes.
Commentaire #88789 écrit par Nejaa Halcyon le 13/04/2013 à 10h00 | 👍🏽 👎🏽
Ajouté à ça, dans ce cas particulier il suffirait d'écrire ça :

switch (choix)
 {
   case 'A' :
   case 'a' :
     // action a
 ...
 }


pour avoir le même fonctionnement.
Commentaire #88791 écrit par Raizarachi le 13/04/2013 à 10h47 | 👍🏽 👎🏽
switch (choix)
 {
 case 'A' :
 case 'a' :
 // action a
 break;
 
 default: 
 break;
 }


C'est un peu mieux mais je chipote :p
Commentaire #88792 écrit par Taiki le 13/04/2013 à 10h48 | 👍🏽 👎🏽
En effet, pour le cas A le break est indispensable, surtout si les points de suspension sous-entendent la présence d'autres case.

Par contre je ne vois pas l'intérêt du default : break;
Commentaire #88793 écrit par Raizarachi le 13/04/2013 à 10h50 | 👍🏽 👎🏽
Il s'agit de gérer les cas imprévu, en particulier si le code évolue et que des cas particuliers sont ajoutés. On peut ajouter un petit log dans le default:
Après, c'est un reflexe que j'ai pris quand j'ai appris le C et c'est dans le pire des cas inutile, dans le meilleur, une aide au debug et éventuellement de rattraper des moments où le code part en vrille.
Commentaire #88794 écrit par Taiki le 13/04/2013 à 10h51 | 👍🏽 👎🏽
il aurait même pu utiliser un toupper(choix) ou tolower(choix) avant d'entrée dans le switch, ça lui aurait divisé le nombre de case par 2 (et éviter les case vides)
Commentaire #88799 écrit par globideuh le 13/04/2013 à 11h21 | 👍🏽 👎🏽
@Taiki : Le problème ne vient pas du default en lui même, mais du break qui le suit. Quelle utilité de préciser qu'il faut quitter le switch dans le cas par défaut sans rien faire d'autre ?
Commentaire #88800 écrit par Skefrep le 13/04/2013 à 11h34 | 👍🏽 👎🏽
> globideuh

Je n'ai vraiment plus l'habitude du C. Quand j'ai voulu regarder la méthode toupper/tolower, la première question que je me suis posé c'était : pourquoi il n'y a pas le nom de la classe avec ? ^^

Sinon question performances, (bien que ce soit extrêmement minime et plus un cas pour débattre qu'autre chose), je ne sais pas quelle est la méthode la plus rapide entre tolower/toupper et case 'a':/case 'A':
Commentaire #88803 écrit par Raizarachi le 13/04/2013 à 11h57 | 👍🏽 👎🏽
En C et C++, il est inutile de mettre un break pour le default.
Par contre, en C# il est obligatoire de terminer le default par un break.
Commentaire #88805 écrit par Shirluban le 13/04/2013 à 12h04 | 👍🏽 👎🏽
Enfin, je parie que le prof lui a juste dit de mettre une structure switch/case sans goto.
Commentaire #88806 écrit par but2ene le 13/04/2013 à 12h12 | 👍🏽 👎🏽
@Raizarachi: c'est surtout pour la lisibilité :)
Commentaire #88819 écrit par globideuh le 13/04/2013 à 13h20 | 👍🏽 👎🏽
@Skefrep: Encore et toujours des reflexes pris il y a longtemps (j'en avait oublié un, je l'ai cherché un certain temps et depuis, je suis un peu paranoïaque sur les breaks) et que si, j'ai un jour envie de remplacer le code du default par un case, c'est plus simple et moins risqué. Again, dans le pire des cas, inutile, dans le meilleur, évite des bugs futur.

@Raizarachi: Sachant que ça n'est probablement pas un macro, ça doit se compter en quelques dizaines d'instructions, à l'avantage du case/case
Commentaire #88829 écrit par Taiki le 13/04/2013 à 14h05 | 👍🏽 👎🏽
Encore mieux, niveau performance (si caractère ascii uniquement):

switch (choix | 32)
{
case 'a':
// action pour 'A' ou 'a'
break;
}

Pour info: c | 32 ignore la casse sur un caractère ascii.
Commentaire #88835 écrit par cpp le 13/04/2013 à 15h14 | 👍🏽 👎🏽
Imagine un programme de ce genre :

[...]
 void funcA() {
     // do something
    if (boolA)
    {
       goto label1;
    }
    else
    {
       // do something else
       goto label2;
    }
 }
 
 void funcB() {
    label1
    // do something
    goto label3;
 }
 
 void funcC() {
    // do something
    label2;
    // do something
    goto label4;
 }
 
 [...]


Maintenant imagine qu'on te donne ce programme à maintenir, et va acheter de la lotion pour cheveux tu vas en avoir besoin.

PS : n'ayant pas touché au C depuis un bail (et le goto c'est le mal) je ne sais plus comment on déclare les labels, donc la syntaxe n'est peut-être pas correcte, mais vous voyez le principe.
Commentaire #88888 écrit par Acorah le 13/04/2013 à 22h54 | 👍🏽 👎🏽
Bonjour,

A tous ceux qui pense que "goto c'est le mal", j'ai envie de dire "pourquoi" ?
Nan c'est vrai, à chaque fois on nous ressort le même vieille argument "regarde ce morceau de code avec 200 ligne et 18 goto, tu y comprends quelque chose ?".
En même temps, j'ai envie de dire que si le gars fait une fonction de 200 lignes et 18 goto, ben c'est déjà mal parti ...

goto peut se révéler extrêmement utile, mais il est communément admit (dans mon entourage, pas de manière général) que sa seul utilisation raisonnable se limite à la gestion des erreurs (lors de la construction d'une structure notamment).
En dehors de ce cas, on préfère éviter le goto effectivement.
Et comme la gestion des erreurs n'est pas la priorité des débutants, on fait un gros raccourci en leur disant "goto c'est le mal, pas touche". (oui, un débutant, ca fait plus un exit(EXIT_FAILURE) qu'entre chose en cas de soucis).

Bref, tout cela pour dire que non, goto n'est pas à jeter, mais a utiliser très précautionneusement.
Et de toute façon, on est censé bien commenter son code, non ? :D

NB : les "on" et autre généralité se limite à mon entourage et ne sont pas a prendre au sens général.
"on" = moi + mes connaissance != tout le monde
Commentaire #88889 écrit par SofEvans le 13/04/2013 à 23h07 | 👍🏽 👎🏽
En C++ / C# la gestion des erreurs peut se faire proprement avec le mécanisme d'exceptions, en C je l'ai déjà vu avec la valeur de retour des fonctions réservée pour ça.
Commentaire #89024 écrit par Raizarachi le 15/04/2013 à 10h21 | 👍🏽 👎🏽
Perso, je vois pas vraiment en quoi c'est un Pebkac... A partir du moment où ça marche, même si la méthode n'est pas des plus optimisée ou galante, pourquoi pas... C'est comme traiter quelqu'un qui fait appel au menu contextuel plutôt qu'aux raccourcis clavier de Pebkac (ben ouais, les raccourcis clavier, c'est vachement plus optimisé, tu gagne 1H par jour au moins !!)
Commentaire #89104 écrit par Araldwenn le 15/04/2013 à 16h22 | 👍🏽 👎🏽