Bonjour est ce que goto est propre a c++ ou non ?
Bonjour est ce que goto est propre a c++ ou non ?
Salut,
Le mot clé goto a été hérité du C, et son usage est fortement déconseillé. En C++, il y a toujours moyen de s'en passer.
Meilleures salutations
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
non, bien au contraire. C'est un héritage de la programmation procedurale de l époque.
Y'a quand même UN cas de figure en C/C++ où le goto est intéressant: une sorte de 'break' pour sortir de multiples boucles.
Certes des alternatives existent, mais c'est plus lent...
Exemple: rechercher un élément dans une matrice
La preuve que c'est vraiment utile: la syntaxe du Java autorise au 'break' de sortir d'une boucle multiple
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 for (int i=0; i<M; ++i) for (int j=0; j<N; ++j) if (A[N*i+j]==a) goto found; found:;
Bof, je préfère, de loin :Envoyé par Charlemagne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int find(T A[], int N, int M, T a) { for(int i = 0; i < M; ++i) for(int j = 0; j < N; ++j) if (A[N*i + j] == a) return N*i + j; return -1; }
Pareil.
Bof. A moins d'être en temps réel, je ne vois vraiment pas l'intérêt de se passer de constructions plus propres.Certes des alternatives existent, mais c'est plus lent...
Moi aussi, je préfère un return, mais c'était un exemple à la con...Envoyé par Sylvain Togni
Bof. A moins d'être en temps réel, je ne vois vraiment pas l'intérêt de se passer de constructions plus propres.Arrêtez de me critiquer, ou bien critiquez donc également Stroustrup.Le principe utilise dans cette preuve me laisse un peu songeur...
Je le cite de son bouquin, sur le paragraphe consacré au 'goto':
Déjà lu un bouquin de C?(...) Un goto peut également être important dans les cas rares pour lesquels une efficacité optimale est indispensable (...)
L'une des applications les plus judicieuses de cette instruction consiste à sortir d'une boucle imbriquée ou d'une instruction switch (un break ne permet de remonter qu'un seul niveau de boucle ou d'instruction switch). Par exemple (...)
Stroustrup cite Java?
Plus sérieusement, l'usage de goto pour cette tâche se défend même si je ne partage pas cet opinion.
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Envoyé par Charlemagne
Ca va mieux maintenant?
Il n'ecrit rien de semblable aou bien critiquez donc également Stroustrup.
Je le cite de son bouquin, sur le paragraphe consacré au 'goto':
Raisonnement que je continue a trouver tres douteux, quelle que soit mon opinion sur les goto et la possibilite de sortir de plusieurs boucles en meme temps.Envoyé par Charlemagne
Tu as deja lu mes messages sur le forum C?Déjà lu un bouquin de C?
Le principe utilise dans cette preuve me laisse un peu songeur...Envoyé par Charlemagne
C'est moche et ça n'est pas beaucoup plus rapide que d'utiliser une condition de sortie de boucle:Envoyé par Charlemagne
Ensuite si tu tiens vraiment à optimiser ce type de chose, commence par utiliser une boucle simple plutôt qu'une double boucle
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 bool found = false; for (int i=0; (i<M) && (!found); ++i) { for (int j=0; j<N; ++j) { if (A[N*i+j]==a) found = true; } }
Maintenant, si tu possèdes la STL c'est tout aussi performant et plus lisible d'utiliser
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 for (int i=0; (i < M*N) && (!found); ++i) { if (A[N*i+j]==a) found = true; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 find(A, A+(M*N), a);
C'est un peu plus long en temps de calcul à ta manière,Envoyé par Jan Rendek
et franchement je trouve le goto plus élégant.
C'est hors de propos: Tu peux effectivement ici ne faire qu'une boucle, mais c'était un exemple à la con pour illustrer une boucle imbriquée... rien de plus.Envoyé par Jan Rendek
Dans ce cas d'une boucle simple, t'aurais dû plutôt utiliser un 'break'.
Tu peux toujours faire part de tes remarques à Stroustrup... que visiblement tu prends également pour un imbécile.
Jan Rendek, si le goto est completement futile, pourquoi bigre fait-il parti du langage, nom de dieu !?
et derniere petite remarque, car bcp de choses ont déja été dites ; en assembleur, le "goto" est indispensable, car toutes les boucles fonctionnent avec ca !
voila, de mon avis perso, c'est pas propre du tout a utiliser, et c'est meme a proscrire, mais ne sois pas faschiste, il existe des cas ou l'on cherche l'optimisation et les performances, et il devient tres utile.
je rapelle que pour programmer haut niveau, il existe des langages meilleurs que le C/C++, mais que ceux ci en revanche ont une place manifeste dans les langages bas niveau et dans l'informatique industrielle.
Le goto est un atavisme de l'assembleur, il n'a quasiment plus sa place en C et encore moins en C++. Son utilisation pour sortir d'une boucle est complètement marginale. Je ne l'utiliserais que si cette boucle est un goulet d'étranglement. De plus, avant de la mettre en pratique j'aimerais voir les benchmarks avec et sans et évaluer le gain que cela représente.
Algorithmiquement les deux méthodes suivantes font exactement le même nombre de comparaisons. La seconde faisant une N*M affectations supplémentaire dans une variable que le compilateur assignera probablement dans un registre.
De toute les manières ce n'est pas une pratique à encourager à quelqu'un qui commence le C ou le C++. Cette solution brise le flot d'exécution normal, masque le véritable algorithme et induit des risques d'erreurs de maintenance.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 bool found = false; for (int i=0; (i<M) && (!found); ++i) { for (int j=0; j<N; ++j) { found = (A[N*i+j]==a); } } ---------------------- for (int i=0; i<M; ++i) for (int j=0; j<N; ++j) if (A[N*i+j]==a) goto found; }
Si j'ai 10 boucles de ce genres, je dois fixer à la main 10 labels différents (found1, found2, found3...), que se passe-t-il quand je fais du 'refactoring' et que je déplace une boucle d'une autre unité de compilation ? Ou bien que j'intervertisse quelques lignes de code aux environs de l'étiquettes ?
Déjà il y a 20 ans, il y avait des tonnes de mise en garde contre le 'goto' en basique. On préconisait de le bannir au profit des 'gosub'. Ce n'est sûrement pas pour le réintroduire maintenant.
En assembleur le goto est indispensable, très bien. Justement son emploi principal est de mettre en oeuvre des boucles et des appels de routines. Si je programme en C c'est justement pour me faciliter le travail et ne pas gérer ces problèmes de sauts conditionnels et d'étiquettes. 'goto' je ne l'ai employé que quand je programmais des drivers, dans du C qui contenait allègrement 60% d'assembleur. Sûrement pas pour faire des boucles imbriquées.
Ensuite, je ne prend pas Stroustrupt pour un imbécile. Cependant, je me méfie des exemples et des citations extraites de leur contexte. Je doute profondémment que Stroustrupt milite pour l'usage systématique des 'goto' pour sortir d'une boucle multiple.
Bref, cette solution n'est en aucun cas plus élégante, ni efficace. Je crois que son seul mérite c'est de faire l33t HaXXor, mais ce n'est en aucun cas à employer dans du développement sérieux.
@toxcct: Si j'interviens dans ces forums c'est dans un but purement altruiste. J'accepte toute critique, mais sûrement pas de me faire traiter de 'fachiste' par quelqu'un que je ne connais ni d'Eve ni d'Adam.
Eternelle polémique.Envoyé par Maria1505
Je suggérrais de s'initier à l'assembleur x86....
même si il n'y a aucun goto dans ton code source en C++ eh bien ton programme une fois compilé cela donnera toujours des jmp,je etc...
Les sauts ne sont ni plus ni moins que des goto en ASM.
Ceci dit il faut éviter d'utiliser goto c'est certain
exemple en C
int a=16;
if (a==20) FaireQQueChose()
En ASM cela va donner
mov ax,10h
cmp ax,10h
je adresse_FaireQQueChose
donc en langage machine cela donnera un goto ...
![]()
goto pose pas des problèmes évidents face au RAII ?
Je ne vois rien. A moins que tu parles des limitations sur les cibles des goto en C++ qui font qu'on ne peut pas sauter un constructeur?Envoyé par loufoque
J'avoue avoir très peu utilisé goto en C++, je ne sais donc pas quelles en sont les restrictions.
Je pensais que c'était comme en C. (Mais bon, en C non plus je connais pas parfaitement)
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
redécouper en fonctions implique un cout de performance pour les appels ou de mémoire dans le cas d'inline...
je n'ai pas dit que c'était toujours vrai, j'ai dit qu'il existe de tres rares cas ou le goto peut éventuellement servir.
ne me fait pas dire ce que je n'ai pas dit, j'ai le goto en horreur.
Partager