Auteur Sujet: Programmation : Le GOTO c'est le maaaaaaal  (Lu 50592 fois)

0 Membres et 1 Invité sur ce sujet

BadMax

  • Client Free adsl
  • Expert
  • *
  • Messages: 3 481
  • Malissard (26)
Programmation : Le GOTO c'est le maaaaaaal
« le: 05 mars 2015 à 11:37:30 »
Edit Vivien : Hors sujet extrait du post Droit de "Bloquer un sujet"

Ah oui, et où ça?

Est-ce que la seule allusion au NAT est polémique, comme le fait de parler de GOTO dans certains cercles? (j'ai cessé de parler plusieurs années à quelqu'un de ma famille à cause de sa phobie du GOTO)

Le GOTO c'est le maaaaaaal

jack

  • Professionnel des télécoms
  • *
  • Messages: 1 674
  • La Madeleine (59)
Le GOTO c'est mal
« Réponse #1 le: 05 mars 2015 à 11:42:53 »
Beuh, le goto est la base de toute programmation (ou presque) : faire des sauts.

goto == if == while == for == function : c'est un jmp

BadMax

  • Client Free adsl
  • Expert
  • *
  • Messages: 3 481
  • Malissard (26)
Le GOTO c'est mal
« Réponse #2 le: 05 mars 2015 à 13:38:28 »
Moi on m'a appris à faire des boucles et à bien structurer mes conditions :) #profAyatollah

Je parle du goto des langages évolués, pas le jmp en assembleur qui lui est incontournable :)

jack

  • Professionnel des télécoms
  • *
  • Messages: 1 674
  • La Madeleine (59)
Le GOTO c'est mal
« Réponse #3 le: 05 mars 2015 à 13:42:40 »
Tu parles d'un langage évolué type C ?

Dans ce type de langage, le goto est exactement comme un if(true) : un saut.

Macharius

  • Réseau FTTH Europ' Essonne (91)
  • Abonné Bbox adsl
  • *
  • Messages: 183
  • La Membrolle sur Choisille (37)
Le GOTO c'est mal
« Réponse #4 le: 05 mars 2015 à 14:53:25 »
Le GOTO c'est mal surtout parce que le code devient illisible (faut retrouver le label correspondant toussa toussa, ...) et qu'au final on fait la même chose avec des instructions conditionnelles ou de boucle qui ont des délimiteurs qui permettent de faciliter la lecture.

Donc oui au concept mais non à l'utilisation de cette instruction satanique (sauf si on n'a pas le choix... genre en batch...)

Bon on est encore en train de bordéliser un topic là ;)

jack

  • Professionnel des télécoms
  • *
  • Messages: 1 674
  • La Madeleine (59)
Le GOTO c'est mal
« Réponse #5 le: 05 mars 2015 à 15:25:08 »
Le GOTO c'est mal surtout parce que le code devient illisible (faut retrouver le label correspondant toussa toussa, ...) et qu'au final on fait la même chose avec des instructions conditionnelles ou de boucle qui ont des délimiteurs qui permettent de faciliter la lecture.

Donc oui au concept mais non à l'utilisation de cette instruction satanique (sauf si on n'a pas le choix... genre en batch...)

Bon on est encore en train de bordéliser un topic là ;)

Ben vois-tu, je ne suis pas (du tout) d'accord avec toi.
Je pense que, comme beaucoup, tu es dans le matraquage des universitaires qui n'ont jamais codé, et qui considère que "on peut faire quelque chose de mauvais avec, donc c'est mauvais".

Les mêmes personnes haissent le C, parcque "tu peux faire de l'allocation mémoire manuelle, et donc des segfault / overflow, et donc c'est mauvais".

Une petite citation pour la route:
Citation de: Doug Gwyn
UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.

L'utilisation du goto peut-être très pratique, en particulier dans la gestion des erreurs, par exemple:
..
        ret = fstatat(dirfd, name, &st, 0);
        if (ret)
                goto out;
..
        if (S_ISDIR(st.st_mode))
                goto out;
..
out:
        fprintf(stderr, "Haha!");
        return -1;

C'est nettement mieux que les autres possibilitées :
- dupliquer le code gestion d'erreur
- créer une fonction à chaque fois

BadMax

  • Client Free adsl
  • Expert
  • *
  • Messages: 3 481
  • Malissard (26)
Le GOTO c'est mal
« Réponse #6 le: 05 mars 2015 à 16:19:52 »
Inquisitionnnnnnnnnnnnn !!!!!!!!!!!!!!

En C, je fais :
 - une fonction pour gérer mes erreurs qui nécessite un simple appel
 - une fonction qui catch les SIGILL ou autre pour indiquer où j'en étais au moment du core dump (avec une simple chaine globale qu'il suffit de mettre à jour suivant la fonction appelée)

kgersen

  • Modérateur
  • Abonné Bbox fibre
  • *
  • Messages: 9 078
  • Paris (75)
Le GOTO c'est mal
« Réponse #7 le: 05 mars 2015 à 16:26:02 »
Citer
L'utilisation du goto peut-être très pratique, en particulier dans la gestion des erreurs.
Ca date un peu ton argument, on a inventer try/throw/catch/finally depuis et meme en C: https://code.google.com/p/exceptions4c  :P

#include "e4c.h"
try {
        ret = fstatat(dirfd, name, &st, 0);
        if (ret)
                throw (RuntimeException,'le stat a foiré !');
..
        if (S_ISDIR(st.st_mode))
                throw (RuntimeException,'booo un répertoire !');
..
}
catch {
        const e4c_exception * exception = e4c_get_exception();
        fprintf(stderr, "Haha! a cause de %s", exception->message);
        return -1;
}


c'est quand meme plus propre et on peut passer la cause plus facilement qu'avec un goto ;) et libérer des ressources avec un finally sans se faire zapper pas un return interne.

et c'est mis en oeuvre par des goto ;)

jack

  • Professionnel des télécoms
  • *
  • Messages: 1 674
  • La Madeleine (59)
Le GOTO c'est mal
« Réponse #8 le: 05 mars 2015 à 17:05:11 »
Bouahaha, trop facile  ;D

Citation de: BadMax
En C, je fais :
 - une fonction pour gérer mes erreurs qui nécessite un simple appel
 - une fonction qui catch les SIGILL ou autre pour indiquer où j'en étais au moment du core dump (avec une simple chaine globale qu'il suffit de mettre à jour suivant la fonction appelée)
Prenons un exemple réel.
J'ai une fonction, qui, dans l'ordre:
- ouvrir un fichier
- alloue de la mémoire
- crée un pool de thread et fait d'autres trucs

Chaque truc est nécessaire pour faire les suivants:
- j'ai besoin de mon fichier avant de threader le truc
- j'ai besoin de la mémoire allouée avant de threader le truc

Donc, je ne peux que swap les deux premières instructions (mais au final, cela ne change rien).
J'ai donc plusieurs cas d'erreur :
- si l'ouverture échoue : return
- si l'allocation échoue : je dois clore le fichier
- si le threading échoue : je dois clore le fichier, et libérer la mémoire

En swappant les deux premières instructions:
- si l'alloc échoue: return
- si l'ouverture échoue: free
- si le threading échoue : clore le fichier, et libérer la mémoire

Dans tout les cas, après exécution des trois opérations, je dois clore le fichier, libérer la mémoire, libérer le pool de thread.

Donc, en faisant une fonction, il faut que je lui donne :
- le fd
- le pointeur sur ma mémoire
- le pointeur sur mon pool

Si je clos le fichier alors qu'il n'est pas ouvert : zut.
Si je libère ma mémoire alors qu'elle n'est pas allouée : zut !
Si je libère le pool alors que la création dudit pool a échouée, humpf

Donc, dans ma fonction, je dois aussi lui donner un moyen de savoir quoi faire des 3 paramètres suscités.

N'est-ce pas un peu compliqué ?  8)


[quote="kergsen"
Ca date un peu ton argument, on a inventer try/throw/catch/finally depuis et meme en C: https://code.google.com/p/exceptions4c  :P
[/quote]
Pour reprendre mon exemple ci-dessus, cela signifie que je dois mettre des try/catch imbriqués, c'est à dire augmenter d'autant la profondeur du code, c'est à dire diminuer d'autant la lisibilité dudit code.

Je trouve que c'est beaucoup faire pour remplacer une solution qui n'a qu'une idéologie contre elle, non ?


Au passage, concernant exceptions4c, je note que le truc utilise des signaux : ce n'est donc pas utilisable sur des programmes multi-threadé (https://code.google.com/p/exceptions4c/wiki/threads); Rien que pour cela, non merci, goto still rulz :D

Amicalement,

kgersen

  • Modérateur
  • Abonné Bbox fibre
  • *
  • Messages: 9 078
  • Paris (75)
Le GOTO c'est mal
« Réponse #9 le: 05 mars 2015 à 18:04:50 »
Je ne pense pas que ce soit par idéologie mais plus pour de la clarté, réutilisation/partage du code, optimisation (pas mal d'optimisations de haut-niveau ne marchent plus quand il y a des goto), portage/transpilation vers d'autre langage, etc

Apres moi, je ne suis pas dogmatique, il m'est arrivé souvent d'utiliser des goto, du moins au début de ma carrière ou sur des très petits projets. Mais j'évite autant que faire ce peut quand même.

Pour ton exemple, t'as pas besoin d'imbriqué les try/catch, un seul suffit. En général on init les variables de ressource a 'null' et dans le finally on libere (dans l'autre sens) celles qui ne sont pas a null.

fichier = NULL;
memoire = NULL;
pool = NULL;
...

try {
 if (! (fichier = open(...))) throw(RuntimeException,"erreur ouverture fichier");
 if (! (memoire = malloc(...)) throw(RuntimeException,"plus de memoire");
 if (! (pool = ...)) throw(RuntimeException,"pas de pool!");
...
catch {
   ... gestion de l'erreur (affichage, log, etc)
}
finally
{
  if (pool) ... // tue les threads, libere le pool;
  if (memoire) free(memoire);
  if (fichier) close(fichier);
}

BadMax

  • Client Free adsl
  • Expert
  • *
  • Messages: 3 481
  • Malissard (26)
Programmation : Le GOTO c'est le maaaaaaal
« Réponse #10 le: 05 mars 2015 à 20:51:41 »
Citer
Si je clos le fichier alors qu'il n'est pas ouvert : zut.
Si je libère ma mémoire alors qu'elle n'est pas allouée : zut !
Si je libère le pool alors que la création dudit pool a échouée, humpf

sortie(code,fd, mem, pool)
{
    if (fd!=0){close(fd);}
    if (mem!=NULL){free(mem);}
    if (pool!=NULL){truckinettoie(pool);}
    exit(code);
}

Des questions ? :)

jack

  • Professionnel des télécoms
  • *
  • Messages: 1 674
  • La Madeleine (59)
Programmation : Le GOTO c'est le maaaaaaal
« Réponse #11 le: 05 mars 2015 à 21:43:46 »
Oui : en quoi est mieux que :
   goto out;


out:
    if (fd!=0)
          close(fd);
    if (mem!=NULL)
          free(mem);
    if (pool!=NULL)
          truckinettoie(pool);