IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Valeur indice en sortie de boucle 'for i := 0 to' différente selon langage (Delphi ou FreePascal sous Lazarus) [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre régulier
    Homme Profil pro
    retraité informaticien
    Inscrit en
    Novembre 2008
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : retraité informaticien

    Informations forums :
    Inscription : Novembre 2008
    Messages : 90
    Points : 75
    Points
    75
    Par défaut Valeur indice en sortie de boucle 'for i := 0 to' différente selon langage (Delphi ou FreePascal sous Lazarus)
    Bonjour à tous.
    Je pense quitter Windows en avril 2014 (fin du support de XP) etcomme j'ai beaucoup de programmes écrits en Delphi 6 je viens de commencer une approche de Lazarus.
    Sympa, on ne perd pas tous ses repères.

    Mais ......

    Le résultat d'un petit test me fait craindre pour la compatibilité entre les versions Delphi6 et Lazarus (tests effectués sous Windows XP).

    J'ai extrait de mon source un petit test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.Button2Click(Sender: TObject);
    var
      i, j : integer;
    begin
      j := 0;
      for i := 1 to 4 do begin
        inc(j);    // j n'est là que pour remplir la boucle
      end;
      showmessage('valeur de i : ' + InttoStr(i));
    end;
    Oh surprise, en tout cas pour moi car les résultats du showmessage ne sont pas les mêmes.

    Bien entendu la procédure ci-dessus n'a été écrite que pour mettre en évidence le phénomène, dans la réalité, il s'agit de parser un buffer qui contient des chaînes de caractères de taille fixe '(padés' par des 0 binaires) et des valeur sur 1, 2, ou 4 octets.

    Qui pourrait m'expliquer pourquoi cette divergence de comportement?

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 873
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 873
    Points : 15 291
    Points
    15 291
    Par défaut
    Yop !
    Citation Envoyé par jjnoui Voir le message
    (...) Qui pourrait m'expliquer pourquoi cette divergence de comportement ?

    Merci
    Pas moi, mais par contre j'ai le souvenir (je ne sais plus dans quel langage, peut-être du C...) du warning d'un compilo avec un message genre "la variable de boucle peut être dans un état indéfini à la sortie de la boucle", ce qui veut dire qu'il vaut mieux ne pas l'utiliser...

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 085
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 085
    Points : 15 507
    Points
    15 507
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    Je ne sais pas exactement de quoi vous parlez dans les lignes suivantes.

    Citation Envoyé par jjnoui Voir le message
    Bien entendu la procédure ci-dessus n'a été écrite que pour mettre en évidence le phénomène, dans la réalité, il s'agit de parser un buffer qui contient des chaînes de caractères de taille fixe '(padés' par des 0 binaires) et des valeur sur 1, 2, ou 4 octets.
    Cela étant dit, je dirais que dans l'exemple que vous donnez, la valeur de i est indéfinie, et il n'est pas vraiment surprenant qu'elle varie d'un compilateur à l'autre. En d'autres termes, je pense que c'est une erreur d'utiliser la valeur de i en dehors de la boucle for : si ça marche, c'est par bonheur.
    Voyez, pour comparaison, le code suivant. Celui-ci, sans aucun doute, donnera toujours le même résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i, j: integer;
    begin
      j := 0;
      i := 1;
      while i <= 4 do
      begin
        Inc(j);
        Inc(i);
      end;
      //Dec(i);
      ShowMessage(IntToStr(i));
    end;
    P.-S. Jipété a été plus rapide que moi.

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 663
    Points
    5 663
    Par défaut
    Pae,

    Je confirme : rien dans la définition du langage ne garantit la valeur du compteur à la sortie de la boucle For, c'est même explicitement dit dans les vieux ouvrages.

    Si tu veux que la valeur soit garantie, il faut utiliser un autre type de boucle.

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 874
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 874
    Points : 11 362
    Points
    11 362
    Billets dans le blog
    6
    Par défaut
    Dans la mesure où la variable j n'est pas utilisé après la boucle, je ne suis même pas sûr que le compilateur n'élimine pas la boucle toute entière si les optimisations n'ont pas été supprimées. Mais peut-être la lecture de i ensuite l'empêche-t-il de la squizzer ? Il faudrait comparer les codes compilés.
    Ensuite, le compilateur peut inverser le sens d'une boucle pour gagner en célérité. Il y a là peut-être motif à différence aussi.

  6. #6
    Membre régulier
    Homme Profil pro
    retraité informaticien
    Inscrit en
    Novembre 2008
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : retraité informaticien

    Informations forums :
    Inscription : Novembre 2008
    Messages : 90
    Points : 75
    Points
    75
    Par défaut
    Bonjour et merci à tous.

    Pour Droggo
    Je suis désolé mais je n'ai plus de vieux bouquins sur delphi ou autres (Internet et Google sont passés par là).

    Avant de poster j'avais fait une recherche sur 'évaluation de la condition if', mais sans succès.

    Si je me posais la question c'est que j'utilise couramment cette méthode, (bon j'ai compris, à tort) et que je ne suis pas sorti de l'auberge pour ma migration vers Linux.

    Pour Tourlourou

    Je pense aussi qu'en cas d'optimisation de code l'instruction
    inc(j);
    n'est pas générée, il s'agissait juste d'un mauvais exemple
    Pour Roland Chastain :

    Mon explication n'était pas très claire.

    un tableau dynamique ( Buffer : array of byte ) contient :

    un champ Ascii sur 32 caractères,
    un 'word',
    deux champ Ascii sur 4 caractères

    pour récuperer les données je fais un appel, pour chaque champ Ascii à une routine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
     
    Champ1 := GetBufferASCIIZ(32);
    Champ2 := // autre routine pour les 'word'
    Champ3 := GetBufferASCIIZ(4);
    Champ4 := GetBufferASCIIZ(4);
     
    function GetBufferASCIIZ(StringLength : integer) : string;
    var
      i : integer;
    begin
      result := '';
      for i := 0 to StringLength - 1 do begin
        if Buffer[BufferPointer] = 0 then break;
        Result := Result + chr(PDBRecordTable[BufferPointer]);
        inc(BufferPointer);
      end;
    //avance du pointeur sur le buffer au champ suivant
      while i < (StringLength) do begin
        inc(i);
        inc(BufferPointer);
      end;
     
    // Appelé par :
    Bien sûr il y a d'autres méthodes mais c'est celle-là que j'ai utilisée.

    Moralité : il ne faut pas jouer avec ce qui n'est pas explicitement défini

    Merci aussi à Jipété

  7. #7
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 561
    Points : 3 951
    Points
    3 951
    Par défaut
    Citation Envoyé par droggo Voir le message
    Pae,

    Je confirme : rien dans la définition du langage ne garantit la valeur du compteur à la sortie de la boucle For, c'est même explicitement dit dans les vieux ouvrages.

    Si tu veux que la valeur soit garantie, il faut utiliser un autre type de boucle.
    Le mieux est de considérer le compteur comme une variable locale, et, si nécessaire, le réaffecter en sortie de boucle.
    Il ne faut faire aucune hypothèse sur la valeur du compteur en sortie, avec un for transformé de manière immédaite en while, le compteur vaudra la dernière borne de l'itération + 1 mais si le compteur est un type intervalle prenant toutes les valeurs possibles, ça pose problème (dépassement du type avec l'implémentation basique avec un while). Cela laisse penser que le compilateur choisir une implémentation en fonction du contexte.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème indice négatif d'une boucle for
    Par samo25 dans le forum MATLAB
    Réponses: 8
    Dernier message: 14/02/2012, 17h26
  2. Utilisations des tableaux en sortie de boucle for
    Par TSI06 dans le forum LabVIEW
    Réponses: 2
    Dernier message: 28/06/2010, 20h24
  3. Problème valeur renvoyée vers word avec boucle for
    Par Basicnav dans le forum Excel
    Réponses: 2
    Dernier message: 26/04/2010, 10h43
  4. [XL-2003] Indices pour cellules dans boucle for
    Par doowy38 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 09/06/2009, 15h51
  5. probleme de resultat en sortie de boucle for
    Par afssaLERH dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/10/2007, 16h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo