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

 C++ Discussion :

Inlining des getters / setters auto avec GCC?


Sujet :

C++

  1. #1
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut Inlining des getters / setters auto avec GCC?
    Bonjour,

    J'ai écrit un algo de clustering en C++ et je cherche à l'optimiser un minimum. Toutefois je me pose une questions concernant les getter/setter de mes classes. Ce sont en majorité de simples "return x" et "x ="

    Ai-je besoin de les déclarer inline ou est-ce que ce genre de chose est automatique lorsqu'on utilise GCC avec les optimisations niveau 2 activées?

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Je commencerais déjà par me poser la question de l'utilité de la plupart de ces fonctions.

    Si, effectivement, un accesseur est de temps en temps utile pour permettre la récupération d'une propriété, un mutateur "simple" ne me semble que rarement adapté

    Ceci dit, l'inlining respecte des règles bien précises:

    • Lorsque tu définis une fonction au sein même de la définition d'une classe, la fonction est réputée être implicitement déclarée inline
    • Pour les autres, seules les fonctions explicitement déclarées inline seront réputées comme telles.
    Si je parle de fonction réputées inline, c'est parce que le mot clé ne fait encore que demander au compilateur de les implémenter de manière inline, mais qu'il reste libre de décider de le faire ou non

    Enfin, certaines options de compilation peuvent modifier la manière dont gcc va créer les fonctions inline

    Tu trouvera la plupart de ces options de compilation ici

  3. #3
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Merci je vais regarder cela.

    Toutefois je pense que dans mon cas l'encapsulation est nécessaire pour les raisons suivantes :

    - J'ai des setter qui déclenchent des mises à jour au sein de l'objet, c'est pas le cas de tous mais ça me semble un peu trash de mixer de l'accès public et du get/set au sein de mes classes.

    - Je souhaite pouvoir retourner mes membres sous forme de référence constantes, (même si je n'ai pas encore résolu tous les problèmes qui vont avec ce mode de faire...)

  4. #4
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Ok j'ai pu trouver la réponse à ma question là dedans.

    Il semble que j'ai le choix entre utiliser les options O3 ou finline-functions, ou alors déclarer explicitement inline (je voulais éviter car j'ai l'impression que ça pollue un peu mon .h mais soit).

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par _skip Voir le message
    Merci je vais regarder cela.

    Toutefois je pense que dans mon cas l'encapsulation est nécessaire pour les raisons suivantes :

    - J'ai des setter qui déclenchent des mises à jour au sein de l'objet, c'est pas le cas de tous mais ça me semble un peu trash de mixer de l'accès public et du get/set au sein de mes classes.
    En toute honnêteté, je me méfie énormément des setters purs et simples:

    Si tu en viens à accepter, pour une raison ou une autre, que l'on aille modifier un membre sans vérifier la validité de la modification ou sans que la modification de ce membre n'entraine une mise à jour d'autres propriétés de l'objet, c'est sans doute qu'il n'y a aucune raison de vouloir "cacher" ce membre au "reste du monde" (et peut être qu'il est bon de se poser la question de l'utilité de ce membre dans la classe envisagée )

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Le seul avantage que j'y vois (pour le moment) c'est qu'étant une méthode de classe, on peut utiliser le polymorphisme dessus (dans la mère on sait que l'on veut modifier une propriété, dans une des filles ça peut correspondre à une affectation bête et méchante (mais faut bien la faire) et dans une autre à un calcul exotique et de multiples vérifications avant modification des attributs membres)

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par CedricMocquillon Voir le message
    Le seul avantage que j'y vois (pour le moment) c'est qu'étant une méthode de classe, on peut utiliser le polymorphisme dessus (dans la mère on sait que l'on veut modifier une propriété, dans une des filles ça peut correspondre à une affectation bête et méchante (mais faut bien la faire) et dans une autre à un calcul exotique et de multiples vérifications avant modification des attributs membres)
    J'ai quand même, sans m'être accordé le temps de la réflexion sur le sujet, beaucoup de mal à imaginer une telle discordance entre deux classes suffisamment proches pour avoir un ancêtre commun

    De plus, j'adhère à l'idée que le simple usage de "set" dans le nom d'une fonction est généralement dangereux car trop "générique".

    C'est la raison pour laquelle tu remarquera que j'utilise les termes accesseurs et mutateurs plutôt que ceux de getter et setter

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Je suis complètement d'accord avec toi et j'ai forcé le trait pour illustrer qu'il peut exister des cas où l'accès par le biais d'une méthode peut s'avérer utile.

    Pour ce qui est du nom get/set je suis d'accord que c'est une horreur et que dans tout les cas c'est à manier avec la plus grande prudence pour éviter de briser l'encapsulation.

  9. #9
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    En fait le gros de mon expérience provient du monde java, dans lequel il est considéré d'usage de ne laisser public aucune donnée membre. Cela se fait au nom de l'encapsulation.

    Dans la pratique, on ne fait souvent qu'une affectation ou un retour d'une valeur sous une forme qu'on essaie de rendre plus ou moins read-only.
    Egalement on se donne la possibilité de rendre le setter plus intelligent ou de faire évoluer la partie non visible à l'avenir tout en gardant la même interface pour le code appelant.

    Dans ce premier cas, ça n'est que rarement aussi simple car si le setter devient plus intelligent ou restrictif, il faudra dans bien des cas prévoir une gestion d'erreurs.

  10. #10
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    En C++ aussi on a coutume de mettre public nos données membres. Et justement au nom de cette encapsulation on évite d'exposer nos membres via un mutateurs. Sinon on brise l'encapsulation et de ce fait on viole la loi de Déméter.

    Un petit article sur l'encapsulation justement :
    http://blog.emmanueldeloget.com/inde...-encapsulation

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Côté inlining, je plussoie sur les propos de Koala : il n'est JAMAIS garanti qu'une fonction déclarée inline le soit réellement... Ce qui peut parfois poser de gros problèmes d'optimisation, d'ailleurs.


    Côté accesseurs : j'ai tendance à ne jamais mettre d'accesseurs "simples", c'est à dire affectant / lisant directement l'attribut. Si c'est le cas, je mets tout simplement l'attribut en public.

    Si par contre un des accesseurs est complexe, alors je mets systématiquement les deux, même si le deuxième est un accesseur simple. Toutefois, je laisse l'attribut public de façon à pouvoir remplacer l'accesseur simple par un accès direct si le besoin s'en fait sentir.

    L'attribut n'est protégé (ou privé) que s'il ne soit jamais être modifié manuellement... Dans ce cas, les accesseurs adéquats sont bien sûr ajoutés.

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par Goten Voir le message
    En C++ aussi on a coutume de mettre public nos données membres. Et justement au nom de cette encapsulation on évite d'exposer nos membres via un mutateurs. Sinon on brise l'encapsulation et de ce fait on viole la loi de Déméter.

    Un petit article sur l'encapsulation justement :
    http://blog.emmanueldeloget.com/inde...-encapsulation
    C'est, entre autre, cet article qui m'a convaincu que (mal) faire de l'encapsulation uniquement pour faire de l'encapsulation est presque pire que de ne pas faire d'encapsulation du tout.

    Ce que je veux dire par là (et qui est bien décrit dans l'article), c'est que, si tu te contente de créer un "getter" et un "setter" sur un membre de ta classe, cela revient, en définitive, à ne pas encapsuler du tout ce membre

    En effet, un membre (ou une variable de manière générale) ne vaut que par les membres (ou les variables) qui l'entourent, par les relations qui les régissent et par les comportements que l'on peut en obtenir.

    Un accesseur sur un membre peut être envisagé si le membre en question est une propriété inhérante à l'objet manipulé (par exemple, la vitesse d'un véhicule), mais cette vitesse (initialisée à ...0 dans le constructeur du véhicule) n'a pas à passer directement (je dirait presque "magiquement") de 0 à 100 m/h.

    C'est parce que nous appellerons un comportement accelerer ou ralentir sur une durée donnée et avec un coefficient donné que nous arriverons à passer de 0 à 100 ou inversement

    Et cette constatation s'applique quasiment toujours

  13. #13
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Oui en effet, le compilateur a le dernier mot. Toutefois si je ne déclare pas explicitement inline, je suis obligé de compiler avec des options d'optimisations plus brutales.

    Actuellement je pense que mes fonctions get/set simples sont de bonnes candidates pour un inlining, d'autant que si je déclare inline manuellement je serai censé pouvoir obtenir des warnings si l'inlining ne se fait pas (faut encore que je regarde mais ça me semble assez bien).

    Le problème en ce moment c'est que je suis en train de passer un code spaghetti moitié C moitié C++ en quelque chose que j'ose appeler "orienté objet" selon mes critères et encapsuler des choses qui ne l'étaient pas du tout et qui sont modifiées à tort-la-rigole dans tous les recoins du programme, c'est pas de la tarte...

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Enfin, il y a un point qui n'a pas été abordé du tout jusqu'à présent...

    Et ce n'est rien d'autre que "est-il réellement intéressant d'inliner des fonctions "

    En effet, il faut être conscient du fait que, si l'inlining permet *généralement* de gagner un peu de temps à l'exécution, il arrive aussi qu'il... en fasse perdre.

    De plus, il faut être conscient du fait que le gain de temps, au vu des performances matérielles actuelles, est réellement très limité, ce qui fait qu'il ne devient réellement intéressant que pour les fonctions qui sont appelées un (très) grand nombre de fois.

    Mais cela indique aussi que, pour être en mesure de juger de la réelle efficacité de l'inlining d'une fonction, il faut être en mesure de faire un profiling approfondi

    Et, pour notre malheur, les différents outils de profiling (et de débuggage) présentent parfois des faiblesses au niveau de la gestion des... fonction inline

    Enfin, le gain apporté par l'inlining est très souvent négligeable par rapport à celui que l'on peut obtenir en optimisant prioritairement l'algorithme utilisé.

    Tout cela pour dire que, bien que les getter / setter "simples" soient, a priori, des candidats idéaux à l'inlining, il reste utile d'évaluer individuellement chaque cas

    Et, bien entendu, s'il est acquis qu'une fonction gagne à être inline, il faut alors qu'elle puisse l'être sans dépendre d'une option de compilation (qui risque d'être absente sur un autre compilateur)

  15. #15
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Le truc est que les setters sont devenus des code smell au même titre que les singletons, la surcharge des opérateurs, le downcasting, les mutex, etc chez bien des gens.
    Pourquoi ? Parce que c'est réfléchir en termes de données au lieu de services. C'est un viol de la loi de Déméter, et du coup je les considère maintenant comme des "décapsuleurs".

    J'avais croisé un site avec un exo assez extrémiste où il fallait faire un programme OO qui respecterait 10 règles. Dans les règles il y avait "9. pas d'accesseur ou de mutateur". Ce qui confirme assez ma vision comme quoi il ne sont pas une mesure positive du respect des principes OO.

  16. #16
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Le truc est que les setters sont devenus des code smell au même titre que les singletons, la surcharge des opérateurs, le downcasting, les mutex, etc chez bien des gens.
    Pourquoi ? Parce que c'est réfléchir en termes de données au lieu de services. C'est un viol de la loi de Déméter, et du coup je les considère maintenant comme des "décapsuleurs".OO.

    Autant tout les autres je vois et je comprends pourquoi, autant j'ai du mal à voir où la surcharge d'opérateurs peut être considérer comme du code smell.
    La première chose qui me vient à l'esprit et qui prouve que justement c'est utile, c'est ocaml qui justement ne supporte pas la surcharge d'opérateur et on se retrouve avec deux opérateurs d'additions...

  17. #17
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Juste pour dire que c'est parfois utilisé mauvais escient.

  18. #18
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Juste pour dire que c'est parfois utilisé mauvais escient.
    Oui, déjà vu un opérateur "+" redéfini pour effectuer un "couplage" de deux instances de classes (= mise en référence croisée l'une de l'autre)... Y'a pas à dire, c'était d'une logique ... illogique.

  19. #19
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Pour en revenir à cette histoire de getter / setter VS accès direct aux membres. Je veux bien admettre que la différence entre des get/set qui font rien et l'accès public est assez mince.

    Il y a juste deux points :
    1) Dans l'idée d'avoir une philosophie cohérente, je préfère ne pas mélanger l'accès public et accès par méthodes dédiées (car j'ai quand même des setters plus intelligents, et des getters read-only).

    2) Actuellement je ne fais que retourner et affecter une variable dans ma classe, ok... Mais si à l'avenir je change des choses à l'intérieur de mon objet? Genre la propriété "nombreLitreEssence" de ma classe "Voiture" n'est plus backée par une simple variable float mais est gérée par d'autres membres de type "Jauge" et "Reservoir"?

    Je crois que je garde plus de liberté de fonctionnement, et donc d'encapsulation. Bon je sais très bien que c'est beau dans la théorie, que souvent dans la pratique ça se passe différemment. Je suis pas du tout là pour vous dire que vous avez tort de laisser vos membres publics, ça se comprend, mais par rapport à mes propres habitudes et si le coût sur la facture est de 0 grâce à l'inlining, je peux tolérer ces get/set même s'ils sont d'un intérêt limité.

    En dehors de ça, vous allez peut être me corriger car j'ai pas fait beaucoup de POO en C++ encore, mais je vois quelques choses qui pourraient m'intéresser :

    Si j'ai pour membre un objet de type X dans ma classe.
    En utilisant un setter prenant une référence de X en paramètre, je peux éviter que quelqu'un me plante un NULL dans cet objet?
    En retournant une référence constante sur mon objet dans un getter, je peux limiter les modifications effectuées sur les membres de mon objet (un concept qui m'a souvent beaucoup manqué en java).


    Citation Envoyé par Mac LAK
    Si par contre un des accesseurs est complexe, alors je mets systématiquement les deux, même si le deuxième est un accesseur simple. Toutefois, je laisse l'attribut public de façon à pouvoir remplacer l'accesseur simple par un accès direct si le besoin s'en fait sentir.
    Perso c'est un risque que je ne prendrai pas systématiquement, de peur que certains commettent des imprudences.

  20. #20
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Tu prends le problème à l'envers.
    On ne doit pas écrire setLitreEssence(), mais remplirReservoir().

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Réponses: 38
    Dernier message: 05/02/2015, 16h30
  2. Réponses: 49
    Dernier message: 02/02/2013, 02h10
  3. Réponses: 3
    Dernier message: 04/05/2012, 11h22
  4. Des getters er des Setters avec visual Studio 2005
    Par zghidi dans le forum Visual Studio
    Réponses: 9
    Dernier message: 27/02/2008, 13h37
  5. [Template] Changer la génération des getter/setter
    Par anthyme dans le forum NetBeans
    Réponses: 2
    Dernier message: 05/07/2007, 09h26

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