IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

faut-il supprimer le mot-clé const?


Sujet :

Langage C++

  1. #1
    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 faut-il supprimer le mot-clé const?
    bonsoir,

    Derrière l'aspect trollesque de la question, il y a, je crois, une question intéressante.

    En effet, si dans une fonction membre constante, on peut:
    1. modifier une variable membre déclarée mutable
    2. modifier des variables globales | statiques
    De plus, sachant qu'à n'importe quel endroit du code on peut casser la constance avec un const_cast, alors question: "à quoi sert le mot-clé const?"

    Une réponse possible est: "ça ajoute de la sémantique, du sens, au code". Donc ça ne serait qu'à titre indicatif à l'attention de la personne qui lira le code?

    Pourtant j'use et j'abuse de const, mais vous voyez, en y réfléchissant (et quand je suis de mauvaise humeur), je me dit: "si le stagiaire peut casser ma resplendissante const-conformité sans avoir besoin de modifier mon code.. à quoi bon?"
    Du coup, je me demande si, plutôt que de supprimer le mot-clé const, il ne serait pas une bonne idée d'en ajouter un. Quelque chose du style pure_const, et qui serait intransigeant avec la const_conformité et qui interdirait les 3 points que j'ai énuméré au début.
    « 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

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    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 113
    Points : 32 960
    Points
    32 960
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    disons que c'est une question de bon sens.
    Et tout comme je peux faire un #define private public avant un include pour biaiser son contenu, je peux faire un const_cast pour passer outre la constance.
    Les 2 cas me sont déjà arrivés, par moi ou déjà vu, est-ce pour autant qu'il faut le faire ? Surement pas ^^ Mais rien n'est tout blanc ou noir, alors avoir de tel hacks peut rendre service.
    Mais ce sont et restent des hacks à mon sens.
    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.

  3. #3
    Membre éprouvé
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Points : 1 081
    Points
    1 081
    Par défaut
    Récemment un article est apparu et il proposait exactement l'inverse : tout soit const par défaut en C++ et marquer par un mot clé ce qui doit muter à l'instar des langages fonctionnels impurs qui autorisent les effets de bords, est-ce que cet article dit quelque chose à quelqu'un ? J'aimerai beaucoup le retrouver.
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  4. #4
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

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

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Le mot clef const ne sert-il pas aussi pour des optimisations lorsqu'il est utilise sur des methodes ?

  5. #5
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Non, c'ets une vielle LU ça.

  6. #6
    Membre expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Points : 3 892
    Points
    3 892
    Par défaut
    Un peu de culture à propos de const et mutable en C++11 :
    http://channel9.msdn.com/posts/C-and...lank-and-blank

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par r0d Voir le message
    1. modifier une variable membre déclarée mutable
    2. modifier des variables globales | statiques
    De plus, sachant qu'à n'importe quel endroit du code on peut casser la constance avec un const_cast, alors question: "à quoi sert le mot-clé const?"
    Pour moi, le point 1 n'est pas une brisure de la "constitude", mais le fait qu'elle représente un const logique, et non pas un const physique. Il est tout à fait légitime quel'on puisse par exemple dans une fonction const modifier un mutex qui protège les accès à une donnée membre.

    Pour le point 2, tu confonds const et pure. Une fonction pure ne doit pas modifier l'état global du programme, alors qu'une fonction const ne fait de promesses que par rapport à une variable en particulier. J'aimerais bien une prise en compte de la pureté en C++.

    Le point 3, il faut faire attention : On n'a pas le droit de faire un const_cast sur une variable constante. Juste sur une variable non constante à laquelle on accèderait par un chemin constant. Mais sinon, je suis assez d'accord que const_cast est généralement problématique. Mais parfois, rarement, indispensable. Comme reinterpret_cast.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    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 JolyLoic Voir le message
    Pour moi, le point 1 n'est pas une brisure de la "constitude", mais le fait qu'elle représente un const logique, et non pas un const physique. Il est tout à fait légitime quel'on puisse par exemple dans une fonction const modifier un mutex qui protège les accès à une donnée membre.
    En effet. D'autant plus que si une variable est déclarée mutable, le but c'est bien qu'elle puisse être modifiée dans les fonction membres constantes.

    Citation Envoyé par JolyLoic Voir le message
    Pour le point 2, tu confonds const et pure. Une fonction pure ne doit pas modifier l'état global du programme, alors qu'une fonction const ne fait de promesses que par rapport à une variable en particulier. J'aimerais bien une prise en compte de la pureté en C++.
    D'où mon idée de pure_const. En effet, la notion de pureté n'est pas vraiment utilisée en c++.
    Mais globalement - et tu met bien le doigt dessus - il y a un manque ici à mon avis: il n'est pas possible d'avoir une fonction membre constante ET pure (à moins d'utiliser une fonction membre statique mais ce n'est pas exactement la même chose).
    J'ai justement en tête l'exemple d'un parser sous forme de machine à état. L'algorithme de parsing est complexe, avec beaucoup de récursivité. Nous aimerions, dans certains cas, pouvoir s'assurer qu'une fonction membre ne va modifier ni l'état de son instance ni l'état du programme (lors de la déclaration des protocoles*, ie. avant de commencer l'implémentation: l'idée c'est de répartir l'implémentation des algos entre plusieurs développeurs, en fournissant un protocole qu'ils ne doivent pas modifier), et que ce ne soit surtout pas une fonction membre statique.



    * j'utilise ici le mot protocole dans le sens de Lieberherr et Holland (le protocole de la classe C est l'ensemble des messages qui peuvent être envoyé à C et à ses instances. Avec, en gros, les messages représentent tout ce qui est public dans la classe C.)
    « 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. #9
    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 518
    Points
    41 518
    Par défaut
    Je suis d'accord avec JolyLoic, les variables membres mutables, à moins d'être mal employées, ont toujours un rôle de "bas niveau" indépendant des "vraies" données:
    • Synchronisation
    • Comptage de références
    • Mise en cache/Évaluation paresseuse

    J'ai peut-être oublié certains usages, mais normalement les variables membres "ordinaires" ne sont pas mutables et de tels mécanismes facilitent la const-correctness du reste (en évitant que de basses considérations système "empêchent" une méthode d'être const).

    Plus préoccupant que le const_cast (qui lui, est facilement repérable par un grep), est le cast C-style; je serais partisan de le traiter comme un reinterpret_cast au lieu d'un cast universel si cela n'était pas un breaking change (ensuite, il y a des considérations comme le cast de void* en void(*)(), qui n'est permis qu'en C-style). Cela rendrait l'usage explicite du const_cast obligatoire, permettant de les repérer facilement.
    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.

  10. #10
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    const est le seul contrat dont on dispose en c++ « pur ». En plus, il a une sémantique bien définie et il est vérifié statiquement. C’est au contraire une garantie très forte, et qui manque dans beaucoup d’autres langages (c# et java en tête).

    J'ai justement en tête l'exemple d'un parser sous forme de machine à état. L'algorithme de parsing est complexe, avec beaucoup de récursivité. Nous aimerions, dans certains cas, pouvoir s'assurer qu'une fonction membre ne va modifier ni l'état de son instance ni l'état du programme (lors de la déclaration des protocoles*, ie. avant de commencer l'implémentation: l'idée c'est de répartir l'implémentation des algos entre plusieurs développeurs, en fournissant un protocole qu'ils ne doivent pas modifier), et que ce ne soit surtout pas une fonction membre statique.
    Si la réaction de ton développeur, c’est de bricoler du const_cast pour passer outre const, change de développeur. Si c’est de l’externalisation à l’autre bout du monde, convainc tes dirigeants que c’est une connerie . Je pense que ce genre de trucs doit se régler avec des scripts grep.

    L’autre solution si tu n’as pas confiance en const, c’est d’employer celles qui a cours dans les langages qui n’ont pas const : fournir un wrapper « read-only » de ta classe, et passer celui-ci en paramètre plutôt que l’objet lui même. À noter qu’un pervers pourra toujours s’en sortir pour quand même te modifier l’objet, mais ce sera plus dur qu’un simple const_cast.

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut
    Je partage l'avis de white_tentacle sur l'intérêt de const dans la vérification par le compilo d'une part contrat (d'ailleurs, white_tentacle, ce n'est pas le seul élément, un bon typage participe aussi de la définition du contrat vérifiable par le compilateur).
    Si rien de standard n'existe pour l'instant en C++ pour contractualiser la pureté, il me semble que GCC a des attributs dans ses extensions pour cela.
    @r0d, je ne comprends pas pourquoi tu dis qu'on ne peut avoir une fonction membre à la fois constante et pure. const n'engage rien en terme de pureté : ni dans un sens ni dans l'autre
    Et si l'objet est un manque de confiance dans les tiers, de toute façon, en C++ tu pourras toujours hacker une zone mémoire.

  12. #12
    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 white_tentacle Voir le message
    À noter qu’un pervers pourra toujours s’en sortir pour quand même te modifier l’objet, mais ce sera plus dur qu’un simple const_cast.
    On peut modifier des constantes même sans const_cast, si on le veut vraiment (et qu'on à pas peur du code dégueu)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
     
    class Foo {
       const int i; // privée et constante
     
    public:
       Foo(): i(42) { }
     
       void p() {
    	  std::cout << i << std::endl;
    	}
    };
     
     
    int main() {
      Foo f;
      int *pi = (int*)&f;
      f.p();
      *pi = 0; // acces et modif d'un membre privé / constant
     
      f.p();
      return 0;
    }

  13. #13
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Vivement le jour ou on pourra reellement planquer les membres prives sans pimpl idiom...

  14. #14
    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 3DArchi Voir le message
    @r0d, je ne comprends pas pourquoi tu dis qu'on ne peut avoir une fonction membre à la fois constante et pure. const n'engage rien en terme de pureté : ni dans un sens ni dans l'autre
    Justement, c'est bien cela que je dit: il n'y a aucune façon de déclarer une fonction membre comme pure. En fait, il n'y a aucune façon déclarer une fonction comme pure, qu'elle soit membre ou pas.
    « 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

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 188
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 188
    Points : 17 136
    Points
    17 136
    Par défaut
    Avec constexpr, on ne peut pas s'en sortir?

    par exemple, la fonction suivante est bien pure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    constexpr int half(int n){
        return n/2;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,
    Citation Envoyé par leternel Voir le message
    Avec constexpr, on ne peut pas s'en sortir?

    par exemple, la fonction suivante est bien pure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    constexpr int half(int n){
        return n/2;
    }
    A vrai dire, ta fonction serait pure avec ou sans constexpr, car ce n'est pas le but de ce mot clé.

    Le but de constexpr est d'informer le compilateur qu'il peut, sous certaines conditions, considérer que cette fonction renvoie une constante de compilation.

    Cependant, cela n'oblige nullement le compilateur à la considérer effectivement comme une constante de compilation car il ne pourra la considérer comme telle que si n est lui-même une constante de compilation (ou le résultat d'une fonction déclarée comme constexpr qui prenait une constante de compilation, et l'on peut remonter comme cela assez haut ).

    Si la valeur de n n'est pas une constante de compilation (par exemple parce que dépendante de la valeur d'une boucle ou d'une décision de l'utilisateur), la fonction sera considérée comme une fonction tout ce qu'il y a de plus normale et appelée de manière tout à fait classique.
    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

  17. #17
    Membre expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Points : 3 892
    Points
    3 892
    Par défaut
    Pour la question "Quand est-ce qu'une fonction constexpr est évaluée à la compilation ?", voir ce post : http://stackoverflow.com/q/14248235
    et plus précisément cette réponse précisée par H.S. : http://stackoverflow.com/a/14248310

  18. #18
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par r0d Voir le message
    Justement, c'est bien cela que je dit: il n'y a aucune façon de déclarer une fonction membre comme pure. En fait, il n'y a aucune façon déclarer une fonction comme pure, qu'elle soit membre ou pas.
    non. c'est ce que dit Loïc. Il manque une façon pour indiquer qu'une fonction est pure en C ou en C++. Je crois que PC Lint (ou peut être d'autres outils d'analyse statique de code) permet de le détecter. Sinon, il reste toujours la bonne vieille (et peu sexy) revue de code.

Discussions similaires

  1. WinRAR: supprimer le mot de passe d'une archive ?
    Par qi130 dans le forum Sécurité
    Réponses: 3
    Dernier message: 23/06/2006, 11h03
  2. [debutant] le mot clé const
    Par r0d dans le forum Débuter
    Réponses: 12
    Dernier message: 21/06/2006, 16h13
  3. [VB6] API CreatePen > faut'il supprimer l'ancien pen ?
    Par hpfx dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 21/04/2006, 16h09
  4. comment supprimer des mots d'un texte
    Par visteur dans le forum Langage
    Réponses: 3
    Dernier message: 16/03/2006, 15h11
  5. Supprimer le mot de passe pour sa
    Par tripper.dim dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 13/01/2005, 12h13

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