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

Langage Delphi Discussion :

BUG dans le langage Delphi


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Par défaut BUG dans le langage Delphi
    Ce n'est pas mon genre de crier au bug dans un langage de programmation et même j'ai plutôt tendance à me méfier des personnes qui font habituellement ce genre de déclaration (car dans 99% des cas c'est plutôt de la mauvaise programmation), mais dans mon cas et après avoir passé une après-midi à chercher un bug dans un code (qui il faut le dire est assez complexe) j'en ai conclu qu'il y a un problème dans la gestion des 'string' dans Delphi.
    Pour m'en assurer j'ai fait le test suivant (nouveau projet vierge, un simple bouton 'Button1' sur la fiche, ajouter un gestionnaire sur le click du bouton puis copier/coller le code ci-dessous) :

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    unit Unit1;
     
    interface
     
     
    uses Forms, Classes, Controls, StdCtrls, Dialogs;
     
    type
      TTestEvent = procedure ( const Value: string ) of object;
     
      TTest = class
      public
         procedure Show( const AText: string;
                         SetParentText: TTestEvent );
      end;
     
      TForm1 = class(TForm)
          Button1: TButton;
          procedure FormCreate(Sender: TObject);
          procedure FormDestroy(Sender: TObject);
          procedure Button1Click(Sender: TObject);
      private
         FText: string;
         FTest: TTest;
      public
         procedure TestShow;
         procedure SetText( const Value: string );
      end;
     
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       FTest:= TTest.Create;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
       FTest.Free;
    end;
     
    procedure TForm1.TestShow;
    begin
       SetText( 'Message1' );
       FTest.Show( FText, SetText );
    end;
     
    { TTest }
    procedure TTest.Show( const AText: string; SetParentText: TTestEvent);
    begin
       ShowMessage( AText );
       SetParentText( 'Message2' );
       ShowMessage( AText );
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
       TestShow;
    end;
     
    procedure TForm1.SetText(const Value: string);
    begin
       FText:= Value;
    end;
     
    end.

    En fait on pourrait simplifier le problème en disant que cela vient du fait que le compilateur envoie un pointeur du string lorsqu'on précise 'const', seulement voilà d'une part le développeur n'est pas censé le savoir, d'autre part avec les compteurs de référence Delphi devrait savoir qu'il ne faut pas écraser le contenu de l'ancienne chaîne de caractères lors de la seconde affectation car il reste une référence dessus. Hors là il "libère" la mémoire ce qui fait que si vous exécutez ce test vous ne verrez pas "Message1" puis "Message1" (et non "Message2") comme cela devrait être le cas mais "Message1" et puis le contenu de la même zone mémoire invalidée (ce qui dans mon cas sous Delphi 7 correspondant à "Project1", le nom de mon projet), ou mieux une violation d'accès ...
    Alors BUG ou pas BUG ?? pour l'instant et jusqu'à ce qu'on me prouve le contraire c'est un BUG. Un argument de type 'const' ne peut-être modifié dans l'ensemble d'un "scope" et là ce n'est pas le cas.

    Ce qui m'étonne encore plus c'est que Delphi alloue une nouvelle zone mémoire au pointeur alors que la nouvelle chaîne à la même taille (je m'attendais d'abord à avoir "Message2"...), donc cela laisse à penser qu'il a détecté que l'ancien zone mémoire est toujours référencé, mais le contenu de l'ancienne est visiblement "invalidé" car il l'utilise de suite pour y stocker d'autres infos, enfin bref... je suis vert, moi qui préconisait à tout le monde dans ma boite de toujours utiliser les 'const' pour les 'string', 'record' et 'array' utilisés comme argument, ça remet tout en cause !!!
    Pour le moment j'ai corrigé un problème d'erreur "violation d'accès" ou "erreur interne" aléatoire juste en supprimant 'const' dans mon prototype de fonction et je trouve cela absoluement anormal !

    Peut-être quelqu'un pourra-t-il me rassurer en m'indiquant que j'ai fait quelque chose de mal, qu'il y a un correctif, ou une autre façon de faire (sans se passer du 'const' qu'il doit y avoir en 10000000 d'exemplaire dans mon projet depuis le temps que j'ai passé la consigne) ?

    Merci de votre aide, si aide possible il y a (sinon merci de votre compassion) car au vue de ce problème je pourrai simplement passer mon string sans préciser 'const' devant bien sûr, mais dans ce cas comment savoir si je ne vais pas avoir le bug ailleurs ? Autant supprimer tous les 'const', et ralentir atrocement certaines fonctions récursives qui avaient gagné beaucoup avec ce fameux 'const' ??? Sans compter que j'en dormirai plus...

    [Edit] en passant 'var' plutôt que 'const' je n'ai plus de messages d'erreur mais à la place mes chaînes de caractères constantes voir leur contenu modifié dans le même scope, c'est toujours pas logique mais au moins le Delphi va réallouer le pointeur plutôt que d'en allouer un nouveau (et que l'ancien pointe sur une zone mémoire plus allouée)... Hum je me demande bien ce que le Delphi fout en interne avec sa gestion de chaînes de caractères, quelqu'un pourrait-il m'expliquer ?

  2. #2
    Membre émérite Avatar de Yurck
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2005
    Messages : 682
    Par défaut
    En effet il s'agit d'un bogue.

    Tu ne peux pas garder tes problèmes pour toi !!!!!

    Me revoilà obliger (déontologie oblige) de revérifier la cinématique de l'ensemble des processus récursifs de mes applis.

    Et un vendredi soir à 17h30 !!!!

    "DVP Nova, les développeurs ne lui disent pas merci"

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Par défaut
    Citation Envoyé par Yurck Voir le message
    En effet il s'agit d'un bogue.

    Tu ne peux pas garder tes problèmes pour toi !!!!!

    Me revoilà obliger (déontologie oblige) de revérifier la cinématique de l'ensemble des processus récursifs de mes applis.

    Et un vendredi soir à 17h30 !!!!

    "DVP Nova, les développeurs ne lui disent pas merci"
    Merci pour ta compassion, et désolé pour toi si tu as eu le "malheur" d'associer traitements récursifs et 'const' (ça devrait être précisé dans l'aide qu'il faut pas !), honnêtement j'ai bien trop la flemme de faire de même pour moi, il faut dire que j'y passerai plusieurs jours sans être sûr d'avoir tout vérifié !


    En fait je pense qu'on peut généraliser le problème et trouver un remède en évitant de passer des paramètres de type non ordinal (string, array, record) en const lors de traitements récursifs sauf que justement les const sont souvent intéressants dans les traitements récursifs alors c'est zuber... enfin c'est quand même limité à un "certain modèle" de schéma récursif (qui est suceptible de modifier les données de l'appelant de la méthode)

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 68
    Par défaut
    A mon sens il serait normal d'obtenir 'Message1" puis "Message2" et non "Message1" et "Message1" comme tu le dis...
    Bien sur tu as passé le paramètre en const, ce qui empêche le compilo de le modifier dans la fonction, mais là forcément c'est ta fonction SetParentText qui va modifier directement la chaine sans que le compilo s'en rende compte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       ShowMessage( AText );
       SetParentText( 'Message2' );
       ShowMessage( AText );
    Disons que ce problème "ne me choque pas". Par contre, d'après ce que tu décris tu n'obtiens pas "Message2" et là c'est plutot bizarre...

  5. #5
    Membre émérite Avatar de Yurck
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2005
    Messages : 682
    Par défaut
    Citation Envoyé par Stef_D Voir le message
    Disons que ce problème "ne me choque pas". Par contre, d'après ce que tu décris tu n'obtiens pas "Message2" et là c'est plutot bizarre...
    Ne pas être choqué soit, mais je dis que c'est chiant et merdique car on devrait afficher sinon message1 au moins message2 et trouver cela bizarre c'est un peu gentil, NON ?

    Enfin il faudrait refaire le test avec Delphi 6 ou moins par curiosité.

  6. #6
    Invité de passage
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1
    Par défaut
    Formidable !

    bug à remonter à la team Delphi alors ?

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Par défaut
    Citation Envoyé par Stef_D Voir le message
    A mon sens il serait normal d'obtenir 'Message1" puis "Message2" et non "Message1" et "Message1" comme tu le dis...
    Bien sur tu as passé le paramètre en const, ce qui empêche le compilo de le modifier dans la fonction, mais là forcément c'est ta fonction SetParentText qui va modifier directement la chaine sans que le compilo s'en rende compte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       ShowMessage( AText );
       SetParentText( 'Message2' );
       ShowMessage( AText );
    Disons que ce problème "ne me choque pas". Par contre, d'après ce que tu décris tu n'obtiens pas "Message2" et là c'est plutot bizarre...

    Non mais c'est CLAIREMENT CHOQUANT ce comportement ! ça devrait afficher "Message1" point ! et si je passe en 'var' alors là effectivement ça peut afficher "Message2" ça reste pseudo logique puisque le delphi précise dans l'aide que dans ce cas la variable est passé par adresse, que la méthode peut modifier le contenu de la variable, etc, etc...

    Quand on passe un 'const' on s'attend à ce que la variable ne change pas son contenu, c'est la moindre des choses, si en plus son contenu devient invalide c'est encore pire (mais cela signifie que Delphi a fait la moitié du traitement : il a allouée une nouvelle zone mémoire sur le changement de texte car il a du détecté que l'ancienne zone devait être gardé. Mais dans un second temps il a marqué cette zone comme libre... et là je comprend pas pourquoi et c'est là à mon avis qu'il y a un bug). Moi j'ai juste testéé avec Delphi7 et 2007

  8. #8
    Membre émérite Avatar de Yurck
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2005
    Messages : 682
    Par défaut
    Citation Envoyé par ZZZzzz2 Voir le message
    le "malheur" d'associer traitements récursifs et 'const'
    Et ben non je n'ai pas fait de mauvaises combinaisons dans les secteurs critiques, on ne peut pas toutes les faire (les conn..).

    Pour ma part les traitements récursifs génériques sont localisés dans trois unités seulement, ces unités s'enrichissent et sont communes à l'ensemble de mes applications delphi de ces 7 dernières années.
    Je peux donc dormir à 99% tranquille.

    C'est bon je suis clean.

    Bon we.

Discussions similaires

  1. event dans une dll delphi a recuperer dans un autre langage
    Par titou640 dans le forum API, COM et SDKs
    Réponses: 12
    Dernier message: 30/09/2011, 12h05
  2. Tout le langage Delphi dans un document.
    Par ornitho dans le forum Langage
    Réponses: 4
    Dernier message: 10/12/2008, 14h52
  3. Bug dans Delphi 7 ?
    Par Teddy dans le forum Delphi
    Réponses: 8
    Dernier message: 26/06/2007, 19h29
  4. Bug dans delphi 2006? Include()
    Par the big ben 5 dans le forum Delphi .NET
    Réponses: 5
    Dernier message: 08/11/2006, 13h42
  5. Dans quel langage a été écrit le compilateur Delphi ?
    Par maamar1979 dans le forum Langage
    Réponses: 1
    Dernier message: 08/07/2006, 09h43

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