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

Delphi Discussion :

function boolean --> logique delphi douteuse ?


Sujet :

Delphi

  1. #1
    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 function boolean --> logique delphi douteuse ?
    Salut,

    Je développe depuis un peu plus de 3 ans en Delphi (je ne connais donc pas tout) et plusieurs fois je me suis fais avoir avec les fameuses fonctions qui retournent un booléen.
    Je m'explique, imaginons la fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function DoAllTasks: boolean;
    begin
      result:= true;
      result:= result and DoTask1;
      result:= result and DoTask2;
      ...
    end;
    Je pense que vous voyez où je veux en venir...
    Le but de ma fonction est donc de faire tout les traitements (qui influent de manière "globale" sur l'application), elle retourne vrai si tout s'est déroulé correctement, faux sinon.
    Mais voilà, ainsi écrite, la fonction peut ne pas fonctionner correctement car si DoTask1 retourne false, alors Delphi va "optimiser" le traitement.
    Cette optimisation sur les booléens est désactivable via un $define (enfin je me comprends ^^) mais j'en ai besoin pour les conditions de ce genre : if ((obj <> nil) and (obj.isDone))...
    Ce qui me chagrine c'est que pour faire fonctionner la fonction malgré tout, on peut faire ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function DoAllTasks: boolean;
    var
      b: boolean;
    begin
      result:= true;
      b:= DoTask1;
      result:= result and b;
      b:= DoTask2;
      result:= result and b;
      ...
    end;
    Et là ça marche !
    Je trouve ça illogique car d'un point de vue algorithmique le code est absolument identique dans les 2 cas ! Delphi devrait donc se comporter de la même manière.
    De mon point de vue, le premier cas devrait permettre l'éxécution de toutes les fonctions, si celles-ci modifient "globalement" le programme.
    Le langage C/C++ prendre en compte cette donnée. Selon le compilateur, il va essayer d'analyser le comportement de la fonction appelée et si elle ne fait qu'un traitement local, il va l'ignorer sinon il l'éxécute pour garder la cohérence dans le traitement global du programme.
    Il existe même un mot clé pour déterminer si une fonction fait un traitement local uniquement pour aider le compilateur à optimiser son code car dans le doute, il assume un traitement global.
    Peut-être existe-t-il un mot clé du même genre en Delphi pour lui indiquer d'éxécuter la fonction quoiqu'il arrive ? Malgré tout je ne trouve pas ça logique, par sécurité il devrait avoir le comportement contraire par défaut.
    La syntaxe "pascal" ne permet pas de faire une affectation et une condition à la fois, y'a donc uniquement ce cas avec les fonctions qui pose problème... à l'inverse de la syntaxe "C" qui oblige le compilateur à avoir une certaine intelligence pour analyser si on a traitement local ou pas.

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Salut

    Est-ce que le code suivante ne suffirait pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function DoAllTasks: boolean;
    begin
      result:= DoTask1;
      result:= DoTask2 and result;
      ...
    end;
    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Re-salut

    Tu peux désactiver localement les évaluations booléennes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    {$B+} 
    function DoAllTasks: boolean;
    begin
      result:= true;
      result:= result and DoTask1;
      result:= result and DoTask2;
      ...
    end;
    {$B-}
    Ce qui suppose que le reste de ton application optimise les évaluations booléennes.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  4. #4
    Membre Expert

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 296
    Par défaut
    Il me semble (à vérifier) qu'en faisant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Result := DoTaskn and Result;
    Delphi n'utilise pas l'optimisation

  5. #5
    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
    Citation Envoyé par e-ric
    Salut

    Est-ce que le code suivante ne suffirait pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function DoAllTasks: boolean;
    begin
      result:= DoTask1;
      result:= DoTask2 and result;
      ...
    end;
    cdlt

    e-ric
    Malheureusement non ça revient exactement à la première portion de code de mon précédent message. Delphi va optimiser...
    J'ai fais exprès de mettre "result:= true" en première ligne pour appuyer le parallèlle entre les 2 codes qui semblent quasi identiques mais qui ne produisent pas le même effet.

    Tu peux désactiver localement les évaluations booléennes
    Effectivement mais je trouve cette solution pas très "élégante".
    Ca fait un peu bricolage pis faut y penser à chaque fois.
    En fait surtout j'aimerai savoir pourquoi Delphi agit ainsi ? ça me semble pas logique.

    Il me semble (à vérifier) qu'en faisant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Result := DoTaskn and Result;
    Delphi n'utilise pas l'optimisation
    Je t'assure que si, et c'est bien ça que je trouve absurde :-/

    Edit : ouppss, non tu as raison, pas dans ce cas justement.
    Comme l'a dit e-ric juste avant =)

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    les dotask ramene un boolean de quel type ?
    je m'explique il peut arriver des probleme sur la recuperation de valeur boolean recupere d'une dll ecrite en c

    car en delphi true et false sont equivalent a 0 ou 1 alors qu'en c c'est 1 ou different de 1 ce qui n'est pas la meme chose lorsque tu applique les operateur boolean


    @+ Phil

  7. #7
    Membre chevronné
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Par défaut
    Vérifis l'option de compilation "Evaluation booléene complete".

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    C'est très curieux, je pensais que l'optimisation suivait l'ordre des opérandes, à savoir que la valeur de la première opérande (cellle de gauche) décidait de l'évaluation de la seconde (celle de droite), d'où ma proposition d'inverser l'ordre des opérandes.

    Dans ce cas, tu n'a pas le choix, utilise la directive conditionnelle {B+} (ou {$BOOLEVAL ON} plus explicite). C'est la solution la plus simple et la plus concise.

    Plein de bonnes raisons
    - Ce n'est pas moins esthétique, c'est concis et suffisant.
    - Cela permet de conserver les optimisations pour le reste du code.
    - Cela avertit le développeur de maintenance (ou peut-être toi dans quelques mois) du comportement particulier de cette fonction.
    - Enfin cela te permet d'écrire un code relativement simple auto-documenté.

    L'élégance est une notion relative, l'efficacité est franchement nécessaire.

    En tant que développeur Delphi, je travaille toujours avec l'hypothèse de l'évaluation booléenne paresseuse. Le fait de voir une telle directive m'incite à approfondir l'analyse (à l'aide de F1).

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  9. #9
    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
    Citation Envoyé par anapurna
    salut

    les dotask ramene un boolean de quel type ?
    je m'explique il peut arriver des probleme sur la recuperation de valeur boolean recupere d'une dll ecrite en c

    car en delphi true et false sont equivalent a 0 ou 1 alors qu'en c c'est 1 ou different de 1 ce qui n'est pas la meme chose lorsque tu applique les operateur boolean


    @+ Phil
    Ce sont des booleans, le type interne à Delphi. Je parle de Delphi uniquement ^^

  10. #10
    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
    Citation Envoyé par Philippe Gormand
    Vérifis l'option de compilation "Evaluation booléene complete".

    Oui je connais cette option, mais je ne veux pas l'activer car une expression du type :
    if ((obj <> nil) and (obj.isReady)) va provoquer des erreurs.

    quand je parlais de mots clés ou autre, je pensais plutot à un mot clé qui permettrait de spécifier à Delphi que telle ou telle fonction ne doit pas être optimisée sur l'évaluation booléenne. Mais en fait je ne pense pas que ce genre de mot clé existe... en fait c'est plutot que j'aimerai comprendre pourquoi Delphi se comporte de manière différente dans les 2 cas. Ca fait pas très... rigoureux pour un langage de programmation ? rigoureux n'est pas le mot qui convient le mieux mais je ne le retrouve plus.

  11. #11
    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
    Citation Envoyé par e-ric
    C'est très curieux, je pensais que l'optimisation suivait l'ordre des opérandes, à savoir que la valeur de la première opérande (cellle de gauche) décidait de l'évaluation de la seconde (celle de droite), d'où ma proposition d'inverser l'ordre des opérandes.

    Dans ce cas, tu n'a pas le choix, utilise la directive conditionnelle {B+} (ou {$BOOLEVAL ON} plus explicite). C'est la solution la plus simple et la plus concise.

    Plein de bonnes raisons
    - Ce n'est pas moins esthétique, c'est concis et suffisant.
    - Cela permet de conserver les optimisations pour le reste du code.
    - Cela avertit le développeur de maintenance (ou peut-être toi dans quelques mois) du comportement particulier de cette fonction.
    - Enfin cela te permet d'écrire un code relativement simple auto-documenté.

    L'élégance est une notion relative, l'efficacité est franchement nécessaire.

    En tant que développeur Delphi, je travaille toujours avec l'hypothèse de l'évaluation booléenne paresseuse. Le fait de voir une telle directive m'incite à approfondir l'analyse (à l'aide de F1).

    cdlt

    e-ric
    Merci pour toutes ces réponses

    Edit : me revoilà...

    D'après toi, si on change le code en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= DoTask1 and result;
    Ca fonctionnerait ? A voir
    Sinon ça serait assez marrant puisqu'on aurait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= result and DoTask1;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= DoTask1 and result;
    qui produirait un résultat différent "d'éxécution"...

    Sinon effectivement on peut choisir de toujours désactiver les optimisations d'évaluations des expressions booléennes, malheureusement on a pas commencé notre logiciel avec cette logique et l'activation de cette option entrainerait un sacré paquet de nouveaux bugs ^^ Mais encore, ce n'est pas réellement une solution que je cherche puisque ma bidouille de passer par une variable temporaire fonctionne. Ce que je cherche à comprendre, c'est pourquoi déjà cette bidouille fonctionne (elle ne devrait pas puisque si Delphi optimiserait jusqu'au bout, ça ne changerait rien) et surtout pourquoi l'expression booléenne global n'est pas évaluée lorsqu'on a un appel de fonction dedans.
    En lisant l'aide de Delphi, j'ai vu qu'un variant provoque l'évaluation totale de l'expression, mais pourquoi en-t-il pas de même pour les fonctions ?

    2ème Edit :
    après essai l'utilisation de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= DoTask1 and result;
    à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= result and DoTask1;
    Suffit à contourner le problème, tout simplement à cause du sens de l'évaluation qui se fait de gauche à droite.
    Tu avais raison e-ric sur ta première réponse, je viens seulement de m'en rendre compte (j'avais pas vu que tu avais inversé les 2 opérandes) ^^
    Mais bon quelque part, ça me choque :-/

  12. #12
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par Stef_D
    Merci pour toutes ces réponses

    Ca fonctionnerait ? A voir
    Sinon ça serait assez marrant puisqu'on aurait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= result and DoTask1;
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= DoTask1 and result;
    qui produirait un résultat différent "d'éxécution"...

    Je dois n'avoir rien compris à la problématique parce que je trouve absolument logique que ça puisse provoquer des résultats différents.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= result and DoTask1;
    Si result est faux, du point de vue de la logique de Bool, le résultat de DoTask1 ne sert plus à rien, le résultat total va donner faux quel que soit celui de DoTask1. Delphi, en RAD performant, décide de ne pas exécuter DoTask1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    result:= DoTask1 and result;
    Delphi lit de gauche à droite. Si c'est inversé, Delphi va tester (donc exécuter) DoTask1 et décider par la suite s'il teste result ou non.

    Du point de vue booléen, c'est parfaitement logique.

  13. #13
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Oui je connais cette option, mais je ne veux pas l'activer car une expression du type :
    if ((obj <> nil) and (obj.isReady)) va provoquer des erreurs.
    Je ne comprends pas... Est-ce que tu veux que Delphi devine quand l'optimisation booléenne fait ton affaire ?

    Encore une fois, je n'ai probablement pas compris le problème...

  14. #14
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Désolé pour les post multiples, je suis en feu

    en fait c'est plutot que j'aimerai comprendre pourquoi Delphi se comporte de manière différente dans les 2 cas.
    Delphi ne se comporte pas de manière différente. Il exécute le code de haut vers le bas et de la gauche vers la droite. Donne lui 2 instructions différentes et c'est normal que les résultats soient différents mais le comportement est le même.

    Mais bon.... Comme je l'ai dit souvent, laissez moi m'auto-citer :

    Citation Envoyé par slimjoe
    je n'ai probablement pas compris le problème...

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Je comprend tes préoccupations mais je pense que tu n'as pas compris ce que je t'ai proposé.

    Le fait qu'il y ait une évaluation booléenne paresseuse implique que le compilateur choisisse selon une règle précise et connue quelle opérande (droite ou gauche) il va évaluer en premier. en respectant l'associativité de l'opérateur AND, c'est évidemment l'opérande de gauche. Fais le test.

    Contrairement aux mathématique pures, l'évaluation du résultat d'un expression suit par un ordre séquentiel. D'où la nécessité de connaître l'odre d'évaluation de opérandes pour un opérateur donné.

    En ce qui concerne la directive B+ elle est valide jusqu'au prochain B- donc pas de problème en ce qui concerne le reste de ton code.

    C'est clair ???

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  16. #16
    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
    Citation Envoyé par slimjoe
    Je ne comprends pas... Est-ce que tu veux que Delphi devine quand l'optimisation booléenne fait ton affaire ?

    Encore une fois, je n'ai probablement pas compris le problème...
    En gros oui, d'autres langages comme le C/C++ le font très bien.
    Et surtout le Delphi le fait bien pour les expressions incluant des variants (surement une contrainte interne), pourquoi ne pas avoir forcé cette contrainte lorsque des fonctions sont utilisées dans l'expression ?
    Si la fonction a une ouverture globale et non locale dans le programme, il est absurde de penser que le compilateur va ignorer son éxécution dans un soucis d'optimisation. Enfin moi ça me semble absurde...

  17. #17
    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
    Citation Envoyé par e-ric
    Je comprend tes préoccupations mais je pense que tu n'as pas compris ce que je t'ai proposé.

    Le fait qu'il y ait une évaluation booléenne paresseuse implique que le compilateur choisisse selon une règle précise et connue quelle opérande (droite ou gauche) il va évaluer en premier. en respectant l'associativité de l'opérateur AND, c'est évidemment l'opérande de gauche. Fais le test.

    Contrairement aux mathématique pures, l'évaluation du résultat d'un expression suit par un ordre séquentiel. D'où la nécessité de connaître l'odre d'évaluation de opérandes pour un opérateur donné.

    En ce qui concerne la directive B+ elle est valide jusqu'au prochain B- donc pas de problème en ce qui concerne le reste de ton code.

    C'est clair ???

    cdlt

    e-ric
    Oui oui j'ai bien compris ce que tu voulais me dire, merci.
    En fait j'ai mal lu ton premier post mais qui répondait exactement au problème. Cependant (après c'est plutot de l'ordre du débat) je ne trouve pas forcément cette approche logique d'un point de vue algorithmique...
    Comme je disais, si task1 modifie "globalement" (désolé de répéter ce terme mais il me semble approprié) le programme, le compilateur ne devrait pas optimiser le code ainsi, du coup c'est à "l'utilisateur" (le développeur reste un utilisateur ici) de prendre garde à ça.

    De même on revient sur le tout premier cas que j'ai cité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function DoAllTasks: boolean;
    begin
      result:= DoTask1;
      result:= result and DoTask2;
      ...
    end;
    qui produit un résultat différent de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function DoAllTasks: boolean;
    var
      b: boolean;
    begin
      result:= DoTask1;
      b:= DoTask2;
      result:= result and b;
      ...
    end;
    bizarre nan ?

  18. #18
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    Citation Envoyé par Stef_D
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function DoAllTasks: boolean;
    begin
      result:= true;
      result:= result and DoTask1;
      result:= result and DoTask2;
      ...
    end;
    a prut prés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    result:=false;
    if not Dotask1 then exit;
    if not Dotask2 then exit;
    ...
    if not Dotaskn then exit;
    result:=true;
    en plus la réponse tu la dis toi meme

    Citation Envoyé par Stef_D
    Le but de ma fonction est donc de faire tout les traitements (qui influent de manière "globale" sur l'application), elle retourne vrai si tout s'est déroulé correctement, faux sinon.
    alors si une et une seul est faux pas la pein d'executé le réste est sa c'est une point fort en delphi (bravo à borland pour son travail d'optimisation en delphi) ,,,
    si tu veux que tous tes fonction s'excute , tu peut par example incémenté un variable et tu le compare a la fin avec une valeur (nbr de fonction):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    function DoAllTasks: boolean;
    var  i:integer;
    begin
      i:=0;
      if DoTask1 then inc(i);
      if DoTask2 then inc(i);
    ....
      if DoTaskn then inc(i);
       result:=(i=n);
    end;
    si tu as besoin simplement de savoir si au moins de tes fonction retourne vrait utlise plutot (OR)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function DoAllTasks: boolean;
    begin
      result:= false;
      result:= result or DoTask1;
      result:= result or DoTask2;
      ...
    end;

  19. #19
    Membre émérite Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Par défaut
    Citation Envoyé par Stef_D

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    function DoAllTasks: boolean;
    begin
      result:= DoTask1;
      result:= result and DoTask2;
      ...
    end;
    qui produit un résultat différent de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function DoAllTasks: boolean;
    var
      b: boolean;
    begin
      result:= DoTask1;
      b:= DoTask2;
      result:= result and b;
      ...
    end;
    bizarre nan ?
    Bizarre ? Non. Un peu dommage ? Probablement.

    Le problème vient du fait que Delphi n'optimise sur une aussi longue portée qu'on le voudrait parfois.

    Dans le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var
      s: string;
    begin
      s := 'Test';
    end;
    La ligne s := 'Test'; n'est pas compilée par Delphi. Toutefois, si tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var
      s1, s2: string;
    begin
      s1 := 'Test';
      s2 := s1;
    end;
    La ligne s := 'Test'; va être compilée. Delphi ne va pas plus loin que la première ligne quand vient le temps d'optimiser.

    C'est probablement ce qu'il se passe avec ton cas #2 de tests booléens.


    [EDIT] Bon... Quand ça va bien.... Je viens de tester mon code et ça compile tout partout... Pourtant j'aurais juré.... Veuillez ignorer ce post alors....

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

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

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Les choix d'optimisation ne sont pas criticables en soi, on est bien contents de les trouver. Un langage de programmation n'est pas un discours mathématiques, il y a des considérations d'efficacité et de faisabilité. Le concepteur du langage fait des choix. Il faut s'en tenir à cela.

    C'est au développeur de connaître ces particularités. C'est son boulot. Je ne suis pas sûr que les compilateurs C ou C++ fassent tant de miracles que cela. Personnellement, je préfère Delphi car la sémantique est plus simple et le contrôle des types plus musclé, en outre, il compile très vite (on peut accroître la fréquence des tests)

    Enfin, il est envisable de ne pas exécuter la suite d'un traitement si l'une des parties du traitement a échoué (c'est même le plus courant). En ce qui concerne ta fonction, si elle retourne False, on sait qu'une partie a échoué mais on ne sait pas déterminer laquelle (sauf si des indications sont fournies par les DoTaskN). Si les traitements sont dépendants, l'erreur d'une tâche peut avoir des conséquences sur les suivantes.

    Cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

Discussions similaires

  1. [function][delphi]problème valeur de retour
    Par daheda dans le forum Delphi
    Réponses: 2
    Dernier message: 14/11/2006, 13h26
  2. Traduction C++/Delphi DLL et function Callback
    Par Crafton dans le forum Langage
    Réponses: 12
    Dernier message: 23/02/2006, 09h55
  3. Réponses: 2
    Dernier message: 17/10/2005, 12h45
  4. function extract du sql et delphi
    Par guy kadima dans le forum Bases de données
    Réponses: 3
    Dernier message: 06/06/2005, 10h08
  5. [Recursivite] function/procedure d'une suite logique
    Par Tata dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 02/03/2005, 16h13

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