Devinez l'effet de cette boucle for - Delphi/Pascal - Programmation
Marsh Posté le 28-10-2002 à 10:46:12
Y a un truc avec les variables de boucle. Je suis pas sur que tu puisse considérer que i vaut 5 lorsque tu sors de la boucle par le break.
Je dirais que i vaut toujours 0 après la boucle
Marsh Posté le 28-10-2002 à 10:47:03
selon l'aide de Delphi, le résultat est imprévisible pour ce genre de cas
Parfois il fait des optimisations bizarres
si tu veux utiliser la variable hors de la boucle faut faire un while
ici c'est un peu comme un for(int i = 0; ....) en C++ : on ne devrait pas pouvoir utiliser i hors de la boucle
Marsh Posté le 28-10-2002 à 10:52:32
J'ai plus de détails. Si on ne met pas le "break" dans la boucle for, Delphi nous fait un avertissement. Si on le met il n'y a pas d'avertissements. Donc le code doit être bon
En fait, le resultat dépend de si on fait des optimisations ou pas. Sans optimisations, i est bien initialisée à 0 par la première instruction, avec les optimisations, dans le cas taille = 0 i n'est jamais initialisée. Et cela sans conseils ou avertissements.
Mais c'est avec Delphi 5. J'espère qu'ils ont corrigés ce comportement dangereux. C'est que depuis que je code en Delphi je suis plus habitué à faire attention à ce genre de chose, pas comme en C alors le compilo a interet à le faire pour moi
PS: pour le for(int i;...) du C++, d'après la norme tu ne peux pas utiliser i après la boucle justement. Ce que seul Visual ne respecte pas mais bon
Marsh Posté le 28-10-2002 à 11:19:14
antp a écrit a écrit : selon l'aide de Delphi, le résultat est imprévisible pour ce genre de cas Parfois il fait des optimisations bizarres si tu veux utiliser la variable hors de la boucle faut faire un while ici c'est un peu comme un for(int i = 0; ....) en C++ : on ne devrait pas pouvoir utiliser i hors de la boucle |
ton "i" hors de la boucle for n'a pas forcément la valeur que tu penses
Rien ne vaut un bon petit while
Marsh Posté le 28-10-2002 à 13:03:21
Kristoph a écrit a écrit : J'ai plus de détails. Si on ne met pas le "break" dans la boucle for, Delphi nous fait un avertissement. Si on le met il n'y a pas d'avertissements. Donc le code doit être bon En fait, le resultat dépend de si on fait des optimisations ou pas. Sans optimisations, i est bien initialisée à 0 par la première instruction, avec les optimisations, dans le cas taille = 0 i n'est jamais initialisée. Et cela sans conseils ou avertissements. Mais c'est avec Delphi 5. J'espère qu'ils ont corrigés ce comportement dangereux. C'est que depuis que je code en Delphi je suis plus habitué à faire attention à ce genre de chose, pas comme en C alors le compilo a interet à le faire pour moi PS: pour le for(int i;...) du C++, d'après la norme tu ne peux pas utiliser i après la boucle justement. Ce que seul Visual ne respecte pas mais bon |
C pas un comportement dangereux...
Elle est pourrie ta boucle
Les break C mal quand on peut les éviter
Les while et do until C pas pour les chiens (spéce de feignase va )
Marsh Posté le 28-10-2002 à 14:00:12
antp a écrit a écrit : selon l'aide de Delphi, le résultat est imprévisible pour ce genre de cas Parfois il fait des optimisations bizarres si tu veux utiliser la variable hors de la boucle faut faire un while ici c'est un peu comme un for(int i = 0; ....) en C++ : on ne devrait pas pouvoir utiliser i hors de la boucle |
Ce ne serait ni un comportement bizarre, ni (c'est la moins que l'on puisse dire) une optimisation : cela signifierait tout simplement qu'une nouvelle variable locale est créée en début de chaque boucle "for" et, que si une autre variable (locale ou non) existe déjà aec ce nom-là, elle est temporairement "masquée" (donc rendue inaccessible) par la variable de boucle.
Ce serait à mon sens un comportement sûr, venant du langage.
Marsh Posté le 28-10-2002 à 14:02:28
par bizarre je voulais dire "auxquelles ont ne s'attend pas"
Marsh Posté le 28-10-2002 à 14:06:30
Quand on raisonne comme un programmeur C++, en effet, ça l'est.
Marsh Posté le 28-10-2002 à 15:13:47
Mais il faut me comprendre. Dans le cas ou je ne met pas de break, je n'ai rien à battre de la valeur de i. Et dans ce cas j'ai un avertissement. Dans le cas ou je met un break, c'est peut-etre que je compte utiliser la valeur de i mais dans ce cas, pas d'avertissement pour me prevenir ! Le problème viens principalement de cette avertissement manquant.
PS: Ca ne change rien au fait que je n'aime pas ce comportement pour le for. Laisser une variable dans un état indéfini c'est mal. Ce comportement est typique d'un variable locale à la boucle for mais ça n'en est pas une.
Marsh Posté le 28-10-2002 à 15:18:20
C'est vrai, ce serait mieux de pas l'optimiser et de faire un truc méga lent... Si ca te plait pas, tu désactives les optimisations et voila, sinon benh tu fais pas un code pourri comme ca si tu veux récupérer la variable, c'est un for pas un while bon sang!
Marsh Posté le 28-10-2002 à 15:21:41
zion a écrit a écrit : C'est vrai, ce serait mieux de pas l'optimiser et de faire un truc méga lent... Si ca te plait pas, tu désactives les optimisations et voila, sinon benh tu fais pas un code pourri comme ca si tu veux récupérer la variable, c'est un for pas un while bon sang! |
Marsh Posté le 28-10-2002 à 15:24:25
[rant]
Pour ce que Delphi et BorlandC++ optimise, c'est vrai que l'on n'a pas besoin d'activer les optimisations, surtout si elles ont des comportement bizarre.
[/rant]
Alors je me repette : oui utiliser le for comme ça est mal. Mais le fait qu'il n'y ait pas d'avertissement est une erreur, surtout quand on considère le fait qu'il y a un avertissement quand on ne met pas de break dans la boucle.
Marsh Posté le 28-10-2002 à 15:25:11
Kristoph a écrit a écrit : [rant] Pour ce que Delphi et BorlandC++ optimise, c'est vrai que l'on n'a pas besoin d'activer les optimisations, surtout si elles ont des comportement bizarre. [/rant] Alors je me repette : oui utiliser le for comme ça est mal. Mais le fait qu'il n'y ait pas d'avertissement est une erreur, surtout quand on considère le fait qu'il y a un avertissement quand on ne met pas de break dans la boucle. |
Marsh Posté le 28-10-2002 à 15:58:16
Kristoph a écrit a écrit : Mais il faut me comprendre. Dans le cas ou je ne met pas de break, je n'ai rien à battre de la valeur de i. Et dans ce cas j'ai un avertissement. Dans le cas ou je met un break, c'est peut-etre que je compte utiliser la valeur de i mais dans ce cas, pas d'avertissement pour me prevenir ! Le problème viens principalement de cette avertissement manquant. PS: Ca ne change rien au fait que je n'aime pas ce comportement pour le for. Laisser une variable dans un état indéfini c'est mal. Ce comportement est typique d'un variable locale à la boucle for mais ça n'en est pas une. |
Je répète ce que j'ai dit : à mon avis, la variable "i" dont tu parles a, en sortie de boucle, une valeur parfaitement définie, puisqu'elle n'a jamais changé de valeur durant la boucle.
Et faire un break au milieu d'une boucle n'a absolument rien à voir avec la portée des variables locales et ne devrait absolument rien y changer.
D'ailleurs, ce n'est pas parce que tu fais un "break" en milieu de boucle que tu veux récupérer la valeur de l'indice de boucle. La preuve, faire un "return" revient à faire un "break", et juste après un "return", la valeur de l'indice de boucle, on s'en tamponne un peu...
Pour finir, il ne faut pas prendre C et C++ comme exemples de bon comportement de langage, ces 2 langages sont les pires langages de haut niveau en matière de sécurité de programmation, et en particulier, l'extrême souplesse de leur boucle "for" est une aberration.
Marsh Posté le 28-10-2002 à 16:05:05
Moi, je te dis que i n'est pas une variable locale à la boucle for. J'aurais pas passé une heure hier à essayer de comprendre pourquoi le prog plante en version optimisée et passe très bien sans aucun avertissement en version debug.
Voici le comportement exacte :
Sans optimisation :
Code :
|
avec optimisation :
Code :
|
Marsh Posté le 28-10-2002 à 16:05:35
bifacemcleod> Pfiouf, j'avais plus le courage de répondre
Marsh Posté le 28-10-2002 à 16:17:20
Bon, t'es têtu jusqu'à la moëlle.
Quand tu veux faire un boucle en asm équivalente à un for, tu vas faire un loop, ok? Donc, tu assignes CX et tu fais ton loop sachant que CX est décrémenté à chaque fois, et que tu quittes si c'est 0.
Le for calcule le nombre d'itérations avant de commencer, si y en a un qui suit pas, "for" F1 ;-). Bref, il va donc calculer le nombre d'itérations dans CX avant de commencer, et donc CX est une variable temporaire à ton for, et heureusement. Evidemment, il va essayer de mettre i directement dans CX quand il va compiler, comme ca c'est toujours ca de gagné pour les calculs (pas besoin de sauver CX), mais si tu passes trop de variables à ta fonction, etc, etc, tes registres sont déjà occupés, il peut pas foutre i comme CX, donc ton I sera pas la valeur du I de ta boucle.
Pfiouf, je sais pas si qqn à suivit
Marsh Posté le 28-10-2002 à 16:19:13
moi j'ai suivi belle explication
Marsh Posté le 28-10-2002 à 16:21:58
Ouf, c'est déjà ca
Au fait, j'utilise souvent le break mais pour des raisons de performance, et j'ai la sale habitude d'apeller des fonctions Delphi en assembleur comme un bourrin
Mais a part pour des raisons de performance, on a rarement besoin
du break, et de toute facon, quand on regarde le code asm généré tout ca est très logique.
Marsh Posté le 28-10-2002 à 16:23:07
Zion : Tu parles de langages de haut niveau et tu me sort de l'assembleur pour expliquer le comportement d'une boucle for ?
J'ai comme l'impression que pour vous le i de la boucle for est local à cette boucle mais ce n'est pas le cas. Le fait de passer dans une boucle for laisse la variable i qui existait déjà dans un état indéfini. Sinon, avec l'affectation i := 0 faite avant le for resterait vraie après le for non ?
Marsh Posté le 28-10-2002 à 16:23:47
zion a écrit a écrit : Bon, t'es têtu jusqu'à la moëlle. Quand tu veux faire un boucle en asm équivalente à un for, tu vas faire un loop, ok? Donc, tu assignes CX et tu fais ton loop sachant que CX est décrémenté à chaque fois, et que tu quittes si c'est 0. Le for calcule le nombre d'itérations avant de commencer, si y en a un qui suit pas, "for" F1 ;-). Bref, il va donc calculer le nombre d'itérations dans CX avant de commencer, et donc CX est une variable temporaire à ton for, et heureusement. Evidemment, il va essayer de mettre i directement dans CX quand il va compiler, comme ca c'est toujours ca de gagné pour les calculs (pas besoin de sauver CX), mais si tu passes trop de variables à ta fonction, etc, etc, tes registres sont déjà occupés, il peut pas foutre i comme CX, donc ton I sera pas la valeur du I de ta boucle. Pfiouf, je sais pas si qqn à suivit |
Non j'déconne et on avait déjà eu cette discution je crois
Marsh Posté le 28-10-2002 à 16:26:18
Kristoph a écrit a écrit : Zion : Tu parles de langages de haut niveau et tu me sort de l'assembleur pour expliquer le comportement d'une boucle for ? J'ai comme l'impression que pour vous le i de la boucle for est local à cette boucle mais ce n'est pas le cas. Le fait de passer dans une boucle for laisse la variable i qui existait déjà dans un état indéfini. Sinon, avec l'affectation i := 0 faite avant le for resterait vraie après le for non ? |
Si tu espères faire du language de haut niveau sans jamais te soucier des implications au niveau le plus bas et au niveau des performances, tu es mal barré
Et oui, le i est LOCAL à la boucle si tu actives les optimisations! Si tu veux que ce soit un comportement algorithmiquement logique, désactives les optimisations, mais si tu refuses de comprendre ce qu'il optimise (ici, une affectation!), je te conseille de faire un peu d'ASM, ca fait du bien
Marsh Posté le 28-10-2002 à 16:28:01
zion a écrit a écrit : Si tu espères faire du language de haut niveau sans jamais te soucier des implications au niveau le plus bas et au niveau des performances, tu es mal barré Et oui, le i est LOCAL à la boucle si tu actives les optimisations! Si tu veux que ce soit un comportement algorithmiquement logique, désactives les optimisations, mais si tu refuses de comprendre ce qu'il optimise (ici, une affectation!), je te conseille de faire un peu d'ASM, ca fait du bien |
Je te sent un peu tendu mon ptit maître
Marsh Posté le 28-10-2002 à 16:32:00
[SDF]Poire a écrit a écrit : Je te sent un peu tendu mon ptit maître |
Oué, il veux le beurre et l'argent du beurre et râle que c'est pas possible et veux pas entendre raison...
Marsh Posté le 28-10-2002 à 16:32:05
Kristoph a écrit a écrit : Sinon, avec l'affectation i := 0 faite avant le for resterait vraie après le for non ? |
il est pas impossible que le compilo n'utilise pas du tout la variable i, et dans ce cas variable i hors de la boucle = variable i de la boucle = registre, non ?
Marsh Posté le 28-10-2002 à 16:37:48
zion a écrit a écrit : Si tu espères faire du language de haut niveau sans jamais te soucier des implications au niveau le plus bas et au niveau des performances, tu es mal barré Et oui, le i est LOCAL à la boucle si tu actives les optimisations! Si tu veux que ce soit un comportement algorithmiquement logique, désactives les optimisations, mais si tu refuses de comprendre ce qu'il optimise (ici, une affectation!), je te conseille de faire un peu d'ASM, ca fait du bien |
Je suis quelqu'un qui programme en Python a chaque fois que possible, alors non, les implications de bas niveau ne me concernent pas en général.
Ensuite, activer les optimisations ne transforme pas la variable i en variable locale à la boucle for. Dans le cas indiqué, i ne recoit jamais de valeur pour taille = 0 . Le compilo a jugé utile de retirer la première ligne de code car il supposait que le for allait écraser cette valeur de toute façon.
Et pour finir, qu'une option de compilation comme les optimisations change le sens du langage c'est bien ça ?
Marsh Posté le 28-10-2002 à 16:43:17
Kristoph a écrit a écrit : Je suis quelqu'un qui programme en Python a chaque fois que possible, alors non, les implications de bas niveau ne me concernent pas en général. |
Tu as de la chance de pas devoir optimiser tes programmes...
/me qui se retient très très fort de troller
Kristoph a écrit a écrit : Ensuite, activer les optimisations ne transforme pas la variable i en variable locale à la boucle for. Dans le cas indiqué, i ne recoit jamais de valeur pour taille = 0 . Le compilo a jugé utile de retirer la première ligne de code car il supposait que le for allait écraser cette valeur de toute façon. |
Oui, et il va même décompter plutot que compter si il juge que tu n'utilises pas la variable dans la boucle... Relis mes explications, ca reste valable.
Kristoph a écrit a écrit : Et pour finir, qu'une option de compilation comme les optimisations change le sens du langage c'est bien ça ? |
Oui, tu veux de l'optimisation/2 ou de l'optimisation. Je préfère que mon programme marche plus vite en programment proprement que d'aller moins vite mais de respecter un truc non conforme. Sache que dans tout cours d'algorithmie, on t'enseigne que le for a une valeur indéterminée en fin d'exécution, si le C++ fait autrement, ou python, on s'en fout.
Marsh Posté le 28-10-2002 à 16:45:05
Sur ce, t'as toutes les explications, ca sert à rien d'en débattre 50 heures, t'as pas envie d'admettre qu'une optimisation rende ton code sale non fonctionel, et c'est bien triste, mais tu sais pourquoi, ca sert à rien d'aller plus loin.
Marsh Posté le 28-10-2002 à 16:51:19
Oui, mon code était sale je l'admet, je l'ai changé. Non je n'admet pas que le fait de mettre un break fasse sauter le Warning du compilateur, et non je n'admet pas qu'une variable indéfinie soit encore accessible sans Warning encore une fois.
Ce concepte va peut etre te faire peur mais, si la variable i n'a plus de sens après la boucle for, c'est qu'elle ne doit plus être accessible du tout ! Après, ne viens pas me parler de raisons d'optimisations car ce n'est pas pour optimiser ton code que le langage te laisse accès à i après la boucle for.
Marsh Posté le 28-10-2002 à 16:52:56
zion a écrit a écrit : Sur ce, t'as toutes les explications, ca sert à rien d'en débattre 50 heures, t'as pas envie d'admettre qu'une optimisation rende ton code sale non fonctionel, et c'est bien triste, mais tu sais pourquoi, ca sert à rien d'aller plus loin. |
Marsh Posté le 28-10-2002 à 16:54:07
Kristoph a écrit a écrit : Ce concepte va peut etre te faire peur mais, si la variable i n'a plus de sens après la boucle for, c'est qu'elle ne doit plus être accessible du tout ! Après, ne viens pas me parler de raisons d'optimisations car ce n'est pas pour optimiser ton code que le langage te laisse accès à i après la boucle for. |
Tu dois être corse toi
Marsh Posté le 28-10-2002 à 16:54:25
Kristoph a écrit a écrit : Oui, mon code était sale je l'admet, je l'ai changé. Non je n'admet pas que le fait de mettre un break fasse sauter le Warning du compilateur, et non je n'admet pas qu'une variable indéfinie soit encore accessible sans Warning encore une fois. Ce concepte va peut etre te faire peur mais, si la variable i n'a plus de sens après la boucle for, c'est qu'elle ne doit plus être accessible du tout ! Après, ne viens pas me parler de raisons d'optimisations car ce n'est pas pour optimiser ton code que le langage te laisse accès à i après la boucle for. |
Lors d'un nickage profond de mémoire le compilateur te prévient à l'avance que tu vas KC qq chose ? Il t'empéche de le faire ?
Super intelligent le compilo...
Marsh Posté le 28-10-2002 à 17:00:02
zion a écrit a écrit : Tu dois être corse toi |
Non Portugais pourquoi ?
Marsh Posté le 28-10-2002 à 17:00:49
[SDF]Poire a écrit a écrit : Lors d'un nickage profond de mémoire le compilateur te prévient à l'avance que tu vas KC qq chose ? Il t'empéche de le faire ? Super intelligent le compilo... |
Le plus d'erreurs que le compilateur attrape/interdit, mieux c'est. ne va pas dire le contraire quand même
Marsh Posté le 28-10-2002 à 17:01:57
Kristoph a écrit a écrit : Le plus d'erreurs que le compilateur attrape/interdit, mieux c'est. ne va pas dire le contraire quand même |
Feignasse
Arréte de rêver et va debugger un thread ou une DLL est on en reparle
Marsh Posté le 28-10-2002 à 17:54:52
[SDF]Poire a écrit a écrit : Feignasse Arréte de rêver et va debugger un thread ou une DLL est on en reparle |
Des threads dans des dlls, c'est plus marrant
Marsh Posté le 28-10-2002 à 17:55:49
ou les threads dans les DLL qui sont des plugins IE, encore mieux, hein
ha la la qu'est ce qu'il a pu se plaindre quand ça plantait
Marsh Posté le 28-10-2002 à 18:02:26
antp a écrit a écrit : ou les threads dans les DLL qui sont des plugins IE, encore mieux, hein ha la la qu'est ce qu'il a pu se plaindre quand ça plantait |
Ouai enfin la ca a "l'air" de marcher
Mais c'est vrai qu'avant de faire ce genre de mofis à la con, je préfererais qu'ils rendent la VCL multithread et qu'ils corrigent certains bugs
Marsh Posté le 28-10-2002 à 10:43:45
Pour les cas ou taille = 0, 1 et 10
Et avec delphi 5. Si les nouvelles versions de Delphi se comportent differement, ça m'interresse de savoir.
Message édité par Kristoph le 28-10-2002 à 10:49:48