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 :

structures simples : services or not services [Débat]


Sujet :

C++

  1. #41
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    @Bousk: Le POD a de meilleures performances et est lui-même plus simple, mais au prix d'avoir une sémantique de valeur incomplète, puisqu'il peut être modifié comme une entité.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  2. #42
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Après, le problème est plus un problème de définition : aliasing strict, alignement correct, etc - tout ça est nécessaire au compilateur pour qu'il puisse vectoriser les calculs (là aussi, avec l'introduction des directives d'alignement dans le langage, le C++11 viens à notre rescousse).
    Et la, on est deja aux limites du C++ : pas de mot cle restrict. Mais meme en encapsulant un pointeur restrict dans un pointeur intelligent du type scoped_array, les compilateurs ont du mal. Donc je ne pense pas qu'on soit en mesure d'qvoir une structure meme simple.

  3. #43
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Nous parlons de structures simples, et donc de structures qui serviront sans doute de "brique de base", en tant que membre, à de nombreuses structures / classes.
    Non, pas forcement vrai. Meme dans le cas de choses complexes, dans le monde du calcul, on procede tres rarement ainsi. Dans tous les codes de calcul que j'ai ecrit, je n'ai que du POD ou du POD encapsule dans un pointeur intelligent et que j'utilise apres comme du POD. Je partage a 100% l'avis de Joel car c'est l'approche usuelle dans le domaine HPC.

  4. #44
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Dommage que Laurent Gomilla ne traine plus sur dvp, j'aurais été curieux d'avoir son avis sur la question. Sa lib est à cheval entre les deux: contraintes de perf importantes d'une part pour les calculs graphiques, et contraintes de modélisation (objet) d'autre part, car il s'agit d'une lib dont le but est d'être simple d'utilisation et robuste.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #45
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    C'était un exemple. Entre parenthèses, tu fourni un exemple de doc de la 1.6 alors que cette version est obsolète.
    Et la doc 2.0 est strictement identique pour ces points.
    http://www.sfml-dev.org/documentatio..._1_1Sprite.php
    http://www.sfml-dev.org/documentatio...1_1Vector2.php


    une sémantique de valeur incomplète, puisqu'il peut être modifié comme une entité
    L'interdiction de modification doit venir du fait qu'on l'utilise de manière const, et non camouflé derrière la présence de membres getter const uniquement.
    Si je veux créer une méthode externe qui modifie la position, je veux en avoir le pouvoir sans fioriture. Je passe ma position par référence et c'est réglé.
    Là non seulement l'utilisateur peut mentir à son application, puisque passer sa position par référence non const, seules des méthodes const existent.
    Mais en plus cette utilisation est doublement source d'erreur et de mauvaise habitude pour lui, puisqu'il a finalement la possibilité de modifier sa position par simple assignation d'une nouvelle position. Vous n'interdisez pas l'opérateur d'assignation n'est-ce pas ? Ni le constructeur par copie ? Sinon vous devez déclarer friend toute classe qui devra manipuler une Position ?
    Pour empêcher ce 2° "problème", il va alors devoir enfin passer par des références constantes, et donc la présence de getter const n'apporte rien de plus qu'un accès direct aux membres, et la "protection : il ne peut pas modifier sa position" est déjà présente.
    La plus-value initiale est donc caduque.

    Ou alors vous manipulez uniquement des copies... bof bof.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #46
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Bousk Voir le message
    L'interdiction de modification doit venir du fait qu'on l'utilise de manière const, et non camouflé derrière la présence de membres getter const uniquement.
    Mais dans ce cas, on ne peut plus l'affecter, le remplacer par une nouvelle valeur.
    Si je veux créer une méthode externe qui modifie la position, je veux en avoir le pouvoir sans fioriture. Je passe ma position par référence et c'est réglé.
    Là non seulement l'utilisateur peut mentir à son application, puisque passer sa position par référence non const, seules des méthodes const existent.
    Mais en plus cette utilisation est doublement source d'erreur et de mauvaise habitude pour lui, puisqu'il a finalement la possibilité de modifier sa position par simple assignation d'une nouvelle position. Vous n'interdisez pas l'opérateur d'assignation n'est-ce pas ? Ni le constructeur par copie ? Sinon vous devez déclarer friend toute classe qui devra manipuler une Position ?
    C'est justement le principe: L'affectation remplace la valeur par une nouvelle, donc c'est normal qu'elle soit autorisée.
    Pour empêcher ce 2° "problème", il va alors devoir enfin passer par des références constantes, et donc la présence de getter const n'apporte rien de plus qu'un accès direct aux membres, et la "protection : il ne peut pas modifier sa position" est déjà présente.
    La plus-value initiale est donc caduque.

    Ou alors vous manipulez uniquement des copies... bof bof.
    La plus-value est qu'on ne peut pas modifier la valeur comme une entité. On ne peut que la remplacer, l'écraser complètement par une autre. Pas de modification partielle.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #47
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    La plus-value est qu'on ne peut pas modifier la valeur comme une entité. On ne peut que la remplacer, l'écraser complètement par une autre. Pas de modification partielle.
    Devoir créer une nouvelle Position, puis l'affecter par l'opération = pour finalement remplacer la position initiale...
    Quand tu te rends comptes que tu feras en général m_position = Position(new_x, m_position.getY()); c'est verbeux au possible et n'apporte... rien ? C'est bien ça, strictement rien.
    Enfin si, ça apporte du temps d'exécution supplémentaire. Eventuellement inliné et réduit.
    La lisibilité n'est est pas améliorée. La sémantique pas plus également.
    m_position.x = new_x; est simple, rapide, on ne peut plus clair pour l'utilisateur.

    Je suis pour le distingo des sémantiques de valeur et entité en général, mais dans ce cas présent ça n'apporte rien du tout.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #48
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Non, pas forcement vrai. Meme dans le cas de choses complexes, dans le monde du calcul, on procede tres rarement ainsi. Dans tous les codes de calcul que j'ai ecrit, je n'ai que du POD ou du POD encapsule dans un pointeur intelligent et que j'utilise apres comme du POD. Je partage a 100% l'avis de Joel car c'est l'approche usuelle dans le domaine HPC.
    Mais HPC est un domaine assez particulier. J'imagine par exemple que vous n'utilisez jamais de smart pointers.
    Enfin c'est pour dire qu'AMHA, toutes ces règles, idiomes et bonnes pratiques sont valables dans le cas général, donc pas toujours. Et finalement, elles deviennent caduques une fois qu'on les a comprise.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  9. #49
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Tu cites exactement la phrase ou je dis que j'utilise des pointeurs intelligents (en fait, je n'ai que ca)

  10. #50
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Devoir créer une nouvelle Position, puis l'affecter par l'opération = pour finalement remplacer la position initiale...
    Quand tu te rends comptes que tu feras en général m_position = Position(new_x, m_position.getY()); c'est verbeux au possible et n'apporte... rien ? C'est bien ça, strictement rien.
    Enfin si, ça apporte du temps d'exécution supplémentaire. Eventuellement inliné et réduit.
    La lisibilité n'est est pas améliorée. La sémantique pas plus également.
    m_position.x = new_x; est simple, rapide, on ne peut plus clair pour l'utilisateur.

    Je suis pour le distingo des sémantiques de valeur et entité en général, mais dans ce cas présent ça n'apporte rien du tout.
    En effet, ça n'apporte pas grand-chose, c'est là la différence entre théorie et pratique. En pratique, on se retrouve à utiliser des POD, ce qui mélange sémantique de valeur et d'entité, parce que ça tend à être plus pratique.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #51
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En effet, ça n'apporte pas grand-chose, c'est là la différence entre théorie et pratique. En pratique, on se retrouve à utiliser des POD, ce qui mélange sémantique de valeur et d'entité, parce que ça tend à être plus pratique.
    Dans un univers (réel) 3D je te l'accorde, ça serait plus pratique... comme je l'ai dit dans un de mes premiers posts, les mecs qui bossent sur HPC ou sur embeeded system, je les comprends, mais c'est de la déformation professionnelle de programmer sous contrainte hyper réduite quand tu peux te permettre le zèle de concevoir des trucs plus robustes, même pour un cout plus important en performance. Apres si on veut pousser le bouchon plus loin, on peut laisser tomber les moteurs 3D existants et puis engager tous les types de Future Crew pour faire un jeu 3D moderne...

    Je ne dis pas qu'il faut pousser ce raisonnement dans l'autre extrême, ce n'est pas parce qu'on a plus de mémoire et que nos processeurs peuvent faire 1000 fois plus qu'avant qu'il faut se dire "c'est bon je m'en fout des histoire de performance", mais si ton environnement et tes contraintes t'autorisent plus que ce que tu ne t'autorise habituellement, autant en profiter pour prendre en compte des aspects de la programmation qui sont souvent déconsidérés, comme la maintenabilité, la réutilisabilité...

    Quelqu'un a parlé de Laurent, et de ce qu'il penserait, et bien pour avoir déjà eu pas mal de conversation de ce style là (et oui je prône les services alors que j'ai toujours pensé donnée) avec lui, sans vouloir parler en son nom, il est plutôt pro-service ; c'est d'ailleurs la dernière conversation que j'ai eu avec lui à ce sujet qui a convertit mon esprit influençable à la notion de service (influençable... en même temps quand quelqu'un comme Laurent vous dit quelque chose vous avez juste envie de boire ses paroles ).

    Edit : voici une des conversations. => (le sujet n'est pas tout à fait le même, mais on peut voir qu'il préfère la conception pensée en terme de service)
    Nullius in verba

  12. #52
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Excusez mon intrusion,
    A travers mon regard très amateur, il me semble plus facile :

    -D'avoir TOUT le temps une fonction pour accéder aux membres d'un objet.
    -De ne pas avoir à penser à mettre const lors de chacune des instanciations d'une structure. (l'objet n'est lui, écrit qu'une fois).

  13. #53
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Dans un univers (réel) 3D je te l'accorde, ça serait plus pratique... comme je l'ai dit dans un de mes premiers posts, les mecs qui bossent sur HPC ou sur embeeded system, je les comprends, mais c'est de la déformation professionnelle de programmer sous contrainte hyper réduite quand tu peux te permettre le zèle de concevoir des trucs plus robustes, même pour un cout plus important en performance. Apres si on veut pousser le bouchon plus loin, on peut laisser tomber les moteurs 3D existants et puis engager tous les types de Future Crew pour faire un jeu 3D moderne...
    Tout depend le type de programmation derriere. Dans mon cas, j'ai les deux. J'ai une appli qui est bourrine, vectorisee, mais en fin de compte, la structure est bien pensee pour l'evolution dans le domaine. S'il avait fallu passer par des accesseurs, je pense que j'aurai perdu 50 a 90% de la perf de l'application (en passant de debug a optimise, je gagne un facteur 10). Sachant que dans mon domaine, on fait la chasse aux 10% de gain !
    L'autre est orientee objet, avec des tableaux qui passent d'un processus a un autre, d'une instance a une autre. Elle est bien plus souple (meme si la premiere version non industrielle ne l'etait pas), et la vectorisation a ete faite avec boost.simd. On aurait pu faire des accesseurs pour recuperer les donnees, et je me suis pose la question (ca aurait permis de calculer a la volee certaines proprietes plutot que de les charger), mais ca ne changerait rien au probleme. Oui, ca me permettrait potentiellement de cacher les details pour ajouter des thread-storage, changer l'ordre de stockage...

    Martin Fowler dit qu'il ne faut pas faire de l'over-engineering. Ca en fait partie (surtout qu'on a les outils pour refactorer un projet en 3 clics de souris !)

  14. #54
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    (surtout qu'on a les outils pour refactorer un projet en 3 clics de souris !)
    C'est un bon argument pour le fait de commencer avec un POD, puis transformer ça en classe respectant complètement la sémantique de valeur plus tard, quand les besoins évoluent.

  15. #55
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonsoir,

    Personnellement je rejoint assez l'avis d'Emmanuel et Joel : j'aurais tendance à commencer avec un POD (enfin des données membres publiques), et si le besoin s'en fait ressentir (si il est réel, il arrivera assez vite sur un élément aussi simple, AMA).

    Pour ce qui est de la pensée service évoqué par Kaamui, pourquoi devrais-t-on associer service à fonction ? Personnellement que ce soit une fonction membre, libre prenant un objet du type considéré en paramètre, une donnée membre, ça reste un service à mes yeux.

    Un point qu'à soulevé Koala01 et qui me touche le plus c'est les deux syntaxes différentes entre une fonction membre et une donnée membre, mais c'est plus lié au langage et je ne suis pas convaincu qu'introduire des indirections pour la corriger soit pertinent.

    Le second point sur l'éventuelle besoin de changement d'implémentation me touche beaucoup moins dans ce cas. En général je suis d'accord avec ce point et c'est un des intérêts de l'encapsulation (séparer interface / implémentation). Avec une classe aussi simple, j'ai tendance à penser que l'interface et l'implémentation sont confondues, et que je n'ai donc pas de besoin de les séparer.

    Dans le cas d'une classe Point, si c'est juste un point au sens d'un couple de réel indépendamment de tout hardware, c'est bien son propre d'offrir deux membres, ni plus ni moins. Si il y a un lien fort avec un besoin hardware comme l'exemple de Koala01 avec son couple dans un tableau C, je vois deux schéma :

    • Soit le besoin est au coeur même de la conception et la solution la plus simple est peut-être de directement faire de ce type un typedef sur std::array<2,int> ...
    • Soit le besoin n'est pas au coeur même de la conception, et dans ce cas j'ai tendance à penser que la solution la plus propre est de n'introduire aucune dépendance (ni dans un sens, ni dans l'autre) et de faire une "couche" d'adaptation pour coupler la conception même et le hardware.


    Si par contre c'est un point au sens géométrique, propre à un espace, là j'aurais tendance à offrir un interface plus complexe qu'un simple couple pour offrir les services nécessaires à des changements de répères, des changements d'implémentaiton, etc. Implémentation qui s'appuiera surement sur une autre classe Point étant simplement un couple.

    J'ai aussi vu l'argument d'avoir une sémantique de valeurs immuables, et cependant lorsque l'idée des classes matrices a été évoqué, ce point est passé à la trappe sous prétexte qu'il faut la voir comme un conteneur. Donc un élément de M(2,1) doit avoir une sémantique de valeur immuable et un élément de M(100,100) non ? Quel est la limite alors ? Et sinon un élément de M(1,1) (un int) la syntaxe n'est pas homogène, on mets ça dans une classe et avec une fonction membre const ?

  16. #56
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Et la, on est deja aux limites du C++ : pas de mot cle restrict. Mais meme en encapsulant un pointeur restrict dans un pointeur intelligent du type scoped_array, les compilateurs ont du mal. Donc je ne pense pas qu'on soit en mesure d'qvoir une structure meme simple.
    Mah, le C++ s'est affranchi du restrict, sous une forme peu orthodoxe, je le reconnais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct v1 {
      float x, y, z, w; 
    } ALIGNED(8);
    struct v2 {
      float x, y, z, w; 
    } ALIGNED(8);
     
    void function(v1 *vec1, v2 *vec2); // le compilateur considère qu'il n'y a pas d'aliasing entre vec1 et vec2 (même si (char*)vec1 == (char*)vec2).
    La supposition d'aliasing des données pointée a disparu avec C99 si je ne m'abuse, même si cette fonctionnalité n'a été implémentée que tardivement dans les compilateurs. La plupart des compilateurs C++ appliquent la même règle, et elle doit être dans C++11 (si elle n'est pas déjà dans C++03).

    Concrètement, ça permet au compilateur d'optimiser encore un peu plus le code, puisque les dépendances entre les variables sont cassées (en pratique, ça a surtout généré pour moi des bugs tordus, parce que le compilateur peut maintenant réordonner le code autour de certains cast ; cf. http://blog.worldofcoding.com/2010/0...-problems.html).

    Je te l'accorde, c'est crade
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  17. #57
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le compilo C++ "assume no aliasing" par défaut désormais?
    Ou comment créer des bugs...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    J'ai aussi vu l'argument d'avoir une sémantique de valeurs immuables, et cependant lorsque l'idée des classes matrices a été évoqué, ce point est passé à la trappe sous prétexte qu'il faut la voir comme un conteneur. Donc un élément de M(2,1) doit avoir une sémantique de valeur immuable et un élément de M(100,100) non ? Quel est la limite alors ? Et sinon un élément de M(1,1) (un int) la syntaxe n'est pas homogène, on mets ça dans une classe et avec une fonction membre const ?
    En fait, il "suffit", peu ou prou de s'intéresser à la définition (celle que l'on trouve dans n'importe quel dico ) du type que l'on veut créer.

    La définition d'une matrice commence sans doute par "un ensemble de...".

    A partir de là, peu importe le nombre d'éléments que va contenir ta matrice, elle aura les caractéristiques d'une collection, à savoir le fait d'être copiable (ou non, en fonction du type d'éléments qu'elle contient), d'être assignable, et de fournir un (ou plusieurs) moyen d'accéder à chacun de ses éléments, dusse-t-elle n'en contenir qu'un seul

    Par contre, un point est un repère, et on pourrait sans doute en dire autant des couleurs, d'un montant, et de tout ce que tu peux assimiler à une valeur.

    Que ton repère puisse "glisser" sur une seule, sur deux dimension(s) ou sur 10 ne changera rien au fait que, si tu fait glisser le curseur d'une seule des dimensions, tu obtiens un nouveau repère.

    l'immuabilité des classes ayant sémantique de valeur ne vient, au final, chaque fois que de cette simple constatation: il n'y a, purement et simplement, pas lieu de fournir une méthode quelconque permettant de modifier les valeurs utilisée par ta classe.

    Le résultat est donc que, effectivement, les seules fonctions qui aient un sens sont des fonctions constantes, mais, encore une fois, ce n'est pas parce que les seules fonctions exposées sont constantes qu'il faut décider de faire n'importe quoi du point de vue de la const correctness: tu as un objet qui est, par nature, immuable, mais tu veilles malgré tout à le transmettre sous la forme d'un objet constant quand il ne doit pas être modifié, autrement, bien qu'étant immuable, tu aurais l'occasion d'assigner à ta référence une autre valeur, et de faire potentiellement des dégâts
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #59
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    N'importe quoi. "Le seul changement qui me parait valable est celui que je connais, et il n'est plus valable, donc plus de raison de prévoir". Je trouve que se satisfaire à ce point de ce qu'on sait est vraiment irritant au plus haut point.
    Je n'ai pas écrit ça sans réfléchir. Pensons en terme de services donc : celui rendu par la classe Position est de contenir les deux coordonnées qui forment une position dans l'espace (quel qu'il soit). Celui rendu par la fonction int Position::x() const est de fournir une coordonnée de cette position. Ça ne peut rien être de plus, sinon tu lui donnes trop de responsabilités. Partant de là, tu écartes donc toute idée de "tests" (suis-je au bord du monde, dois-je inverser y parce que je suis dans un miroir, etc.). Cette fonction ne feras jamais rien d'autre que de retourner la valeur de x. J'espère qu'on est d'accord jusque là.

    La seule autre chose que tu peux donc modifier, c'est l'exemple donné par Koala : comment est stockée cette valeur et comment on y accède. Deux variables séparées, un tableau de deux éléments, un pointeur vers une mémoire gérée manuellement, un valarray, ... Et là tu peux effectivement faire des changements dans ta classe qui auront des répercussions dans le code appelant. Mais même alors, pourquoi modifier la classe si un tel besoin se fait sentir ? Revenons aux services : on a besoin d'obtenir la position sous forme d'un valarray. Est-ce à Position de le fournir ? Ou faut-il laisser une fonction libre faire la conversion ?

    Je n'ai rien contre l'encapsulation. Mais si je me permets d'intervenir sur ce sujet, c'est que j'en ai déjà écrit plusieurs classes de ce type : des Vector3, des Point2, et j'en passe. Au début, suivant les conseils que j'avais pu lire sur ce forum et ailleurs, qui me disaient que l'encapsulation c'était bien, j'ai sagement caché mes données membres et utilisé des fonctions membres pour y accéder. À ce jour, ça ne m'a jamais servi à rien d'autre que de m'user les doigts. Je souhaite juste éviter ça à l'OP.

    Citation Envoyé par Kaamui Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void setX(const int x) { pos = Position(x, (const int)spTidus.pos().y) }
    Je pense que, quand on en arrive à ce niveau là, il faut se poser la question : qu'est ce qu'on gagne en faisant ça, et qu'est ce qu'on perd. De mon point de vue, le gain est faible (voir nul, cf. plus haut, mais je ne veux pas débattre là dessus), et le coût plus élevé qu'il n'y paraît. Pour une raison discutable (eh oui, on en discute ici même), on se met des boulets aux pieds :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void Tidus::deplacer(const int dx, const int dy) {
        pos = Position(pos.x() + dx, pos.y() + dy);
    }
    En remplaçant cette classe Position qui fait tant débat par une structure Vector2 dénuée de sémantique (comme dans la SFML), le code est plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void Tidus::deplacer(const Vector2& dpos) {
        pos += dpos;
    }
    Ce n'est pas une question de performance ici, mais une question de rapidité d'écriture (moins de temps passé à écrire = plus de temps pour réfléchir), de concision (moins de caractères à taper = moins de chance de faire des erreurs) et de clarté (moins de caractères à lire et opérations explicites = code plus rapidement compris).

    Là encore, je n'ai rien contre le code verbeux (je n'utilise jamais de using namespace), mais seulement quand ça apporte quelque chose : que ça lève une ambiguïté pour le lecteur, ou que ça empêche de faire des bêtises. Ici je ne vois ni l'un ni l'autre.

    Pour référence, les deux seules bibliothèques que je connais qui traitent ce sujet :

  20. #60
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @koala01: Je pense que tu as mal compris ce que je voulais dire (je parlais de matrice au sens mathématique du terme). Ce passage de mon message était là pour mettre en évidence qu'un point ou même qu'une simple valeur (*) c'est (**) une matrice, alors pourquoi traiter un point, un vecteur, un int, une matrice de manières différentes ?

    (*) Je force le trait volontairement pour insister, mais l'idée est quand même là.
    (**) C'est loin d'être parfaitement rigoureux, mais on va faire avec : au sein de cette discussion, ce sont bien tous des familles.

    PS: Et la définition d'une matrice ne sera jamais "un ensemble de ...".

Discussions similaires

  1. service IIS not installed in u computer
    Par elgafsi86 dans le forum IIS
    Réponses: 0
    Dernier message: 09/03/2010, 15h08
  2. Le plus simple pour créer un service web ?
    Par goeland444 dans le forum Services Web
    Réponses: 0
    Dernier message: 22/07/2008, 15h43
  3. Structure d'une table pour service production
    Par lg022 dans le forum Schéma
    Réponses: 2
    Dernier message: 24/04/2008, 10h27
  4. Réponses: 8
    Dernier message: 22/11/2006, 08h54
  5. Problème "The specified service does not exist as an ..
    Par Rimak2 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 23/05/2005, 21h24

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