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

EDI Delphi Discussion :

Différence de compilation OVERLOAD D2007-D2009


Sujet :

EDI Delphi

  1. #1
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut Différence de compilation OVERLOAD D2007-D2009
    Salut à tous !

    Avec deux unités contenant chacune une procédure du même nom définie en overload.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    unit Unit1;
     
    interface
     
    procedure Update(aXML :string); overload;
     
    implementation
     
    procedure Update(aXML :string);
    begin
    end;
     
    end.
    et

    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
    unit Unit2;
     
    interface
     
    uses SysUtils;
     
    procedure Update(aFileName :TFileName); overload;
    procedure DoUpdate;
     
    implementation
     
    uses Unit1;
     
    procedure Update(aFileName :TFileName);
    begin
    end;
     
    procedure DoUpdate;
    begin
      Update('c:\temp\test.xml');
    end;
     
    end.
    Delphi 2007 (et sans doute les versions précédentes)
    L'erreur Appel surchargé ambigu est générée à la compilation. (TFileName étant de type string)

    Delphi 2009
    Aucune erreur à la compilation, mais l'appel à Update dans la procédure DoUpdate (Unit2) est redirigé sur la procédure Update de la Unit1 . Alors qu'on s'attendrait plutôt à ce que la procédure dans l'unité courante soit prioritaire ou qu'au minimum l'inclusion de la Unit1 dans l'interface ou l'implémentation permette une différenciation.

    Pour que l'appel soit correct:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Unit2.Update('c:\temp\test.xml');
    //ou
    Update(TFileName('c:\temp\test.xml'));
    Bien sûr, ceci fonctionne correctement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure DoUpdate;
    var
      FileName :TFileName;
    begin
      FileName := 'c:\temp\test.xml';
      Update(FileName);
    end;
    A bon entendeur...

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    bon non, le chaine constante n'est pas un TFileName, c'est donc logique que la version "string" soit invoquée

    ça t'apprendra à jouer avec les overload !
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    Ok, pertinent

    Mais alors pourquoi est-ce ambigu sous D2007 .

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    il n'y aurait pas non plus une histoire de String Ansi et Unicode en Delphi2009 qui facilite la résolution ?

    TFileName est-il le même dans le deux Delphi donc String (Ansi 2007, UniCode 2009)

    Sinon, ils ont du renforcé le compilateur sur la gestion de informations de type, il ne doit plus considérer le TFileName comme une simple string mais comme un type à part entière ...

    faudrait essayer la même chose avec un Double et un TDateTime par exemple ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    C'est un type distinct, comme précédemment.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TFileName = type string;
    Mais les génériques sont passés par là. Certainement une cause à effet .

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Ok, pertinent

    Mais alors pourquoi est-ce ambigu sous D2007 .
    parce que ton code l'est

    je pense que c'est en effet une faiblesse du compilateur qui a donc été ensuite corrigée...mais je trouve personnellement que les overload sont casse gueule car (en admettant que le compilateur ne se trompe pas) tu ne sais plus forcément ce que tu fais

    EDIT: d'ailleurs je ne savais pas que l'overload fonctionnait entre deux unités distinctes...mais je trouve ça d'autant plus casse gueule ! Imagine que tu ne soit pas l'auteur de la version TFileName et que tu penses invoquer la version string en lui passant un TOpenDialog.FileName ! bonjour les dégâts
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    N'ait crainte, je reprenais simplement une ancienne unité et me suis retrouvé avec ce "conflit" de nom. Le but n'était pas d'éparpiller la gestion dans plusieurs unités . (J'ai d'ores et déjà renommé les nouvelles procédures)

    Ce qui est casse-gueule est surtout que le type distinct TFileName puisse être assimilé à une string lorsque ça arrange le compilateur .

    Edit:
    EDIT: d'ailleurs je ne savais pas que l'overload fonctionnait entre deux unités distinctes...mais je trouve ça d'autant plus casse gueule ! Imagine que tu ne soit pas l'auteur de la version TFileName et que tu penses invoquer la version string en lui passant un TOpenDialog.FileName ! bonjour les dégâts
    Je l'ai appris à mes dépends aussi

  8. #8
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    ...mais je trouve personnellement que les overload sont casse gueule car (en admettant que le compilateur ne se trompe pas) tu ne sais plus forcément ce que tu fais
    Ca dépend comment on utilise l'overload. Personnellement je ne l'utilise qu'avec un nombre de paramètres différents. Sinon avec les convertions implicites (et certain langages vont beaucoup plus loin que Delphi de ce côté là) bonjour les déjats en effet.

    Citation Envoyé par Andnotor Voir le message
    Ce qui est casse-gueule est surtout que le type distinct TFileName puisse être assimilé à une string lorsque ça arrange le compilateur .
    C'est ce qui arrive avec les conversions implicites.
    Moi c'est plutôt le fait que maintenant ça ne soient plus ambigue qui me dérrange.

  9. #9
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    C'est ce qui arrive avec les conversions implicites.
    Moi c'est plutôt le fait que maintenant ça ne soient plus ambigue qui me dérrange.
    Et pourquoi cela ? Nous avons malheurseusement été habitués à certaines approximations, mais dans sa déclaration, TFileName <> string.

  10. #10
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Certes, les déclarations sont différentes.
    Mais pour affecter TFileName, il faut bien pouvoir faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var
      filename : TFileName;
      fichier : string;
    begin
      filename := 'Fichier1'; // cas 1 : affectation directe.
      fichier := 'Fichier1'; // cas 2 : on affecte un string
      filename := fichier; // cas 3 : on affecte un string à TFileName.
    Dans le cas 1: On affecte un string à un TFileName. Il faut soit que la convertion implicite se fasse, soit que l'affectation soit interdite puisque 'Fichier1' est un string et pas un TFileName. A moins de typer 'Fichier1' directement en TFileName ou de considérer que la valeur immédiate n'est pas typée et qu'on peut la typer en fonction des besoins.

    Cas 2 : C'est l'affectation normale d'un string. Pour que ça fonctionne, il faut bien que 'Fichier1' soit typé comme un string et pas un TFileName.

    Cas 3 : fichier est un string. Soit on dit que string<>TFileName et il faut déclencher une erreur à la compile. Soit on considère que la conversion implicite doit s'effectuer.

    Du moment que la convertion implicite s'effectue, ça ne sert à rien de déclarer deux types différents. Du fait de la conversion implicite, ils sont équivalents.

    Comme Delphi fait la convertion implicite, il y a bel et bien ambiguité. D2007 signalait l'ambiguité, je trouve ça normale.
    Maintenant D2009 continue à faire la conversion implicite, mais de temps en temps, il décide de ne pas la faire.
    Le contrôle des types commence à devenir bancal !


    Remarque, dans le même ordre d'esprit :
    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
     
    // Version 1
    function Carre(v : integer) : integer; overload;
    begin
      result := v * v;
    end;
     
    // Version 2
    function Carre(v : int64) : int64; overload;
    begin
      result := v * v;
    end;
     
    var
      r : integer;
      d : double;
    begin
      r := Carre(2); // Cas 1
      d := 1.0;
      r := Carre(Round(d));  // Cas 2
      r := Carre(Round(1.0)); // Cas 3
    end.
    Quelle version de Carre est appelée dans chaque cas ?

    Dans le cas 1, il appelle la version 1 (Pourtant 1 est un integer, mais 1 est aussi un int64. Il devrait y avoir ambiguité. Mais Delphi n'a jamais ralé la dessus).
    Dans le cas 2, il appelle la version 2. Ca veut dire que Round retourne un int64.
    Dans le cas 3, il appelle.... la version 1. Donc Round possède un overload qui retourne un integer... non en fait le compilateur a considéré que 1.0 est un entier et a supprimé l'appel à Round. Donc en fait, on se retrouve dans le cas 1.

    Par contre si j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var
      b : byte;
    begin
      b := 1.0;
    Cette fois j'obtiens une erreur ! Le 1.0 qui était pourtant un entier égal à 1 tout à l'heure au moment de la compilation, n'est plus un entier maintenant !

    Bref, le compilateur avec son contrôl des types n'est pas cohérent.

    PS: C'est à cause de ce genre de truc que je ne fais pas d'overload sur la base des types des paramètres.

  11. #11
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 695
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 695
    Points : 13 133
    Points
    13 133
    Par défaut
    Alors j'ai fait un essai (Copier/coller) .

    C'est bien le comportement sous D2009. Par contre sous D2007, c'est la version 2 qui est appelée par le cas 3 !
    Quant à l'aide, elle dit que Round renvoi toujours un Int64 .

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

Discussions similaires

  1. Différence de compilation en RedHat 5.3
    Par awalter1 dans le forum Linux
    Réponses: 1
    Dernier message: 01/05/2009, 15h40
  2. Différences à la compilation
    Par anonyme dans le forum Débuter
    Réponses: 7
    Dernier message: 20/05/2008, 14h36
  3. Réponses: 15
    Dernier message: 20/03/2008, 09h33
  4. différence entre "compile" et "build"
    Par pyrrhon_ dans le forum Visual C++
    Réponses: 3
    Dernier message: 24/04/2007, 23h04
  5. Réponses: 1
    Dernier message: 01/02/2006, 23h39

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