Comment êtes-vous devenu converti en constance? [fermé]

25

Après 15 ans de C ++, je n'ai toujours pas appris à aimer utiliser const. Je comprends que c'est utile, mais je n'ai jamais réellement été dans une situation où être const correct aurait évité le problème auquel j'étais confronté.

Alors, comment en êtes-vous venu à aimer les avantages des consts?

grok
la source
3
Je pense que l'exactitude de const est plus d'être correcte qu'un outil pour résoudre un problème comme un if constrcut ou un opérateur sizeof.
legends2k
9
"La raison pour laquelle const fonctionne en C ++ est que vous pouvez le rejeter. Si vous ne pouviez pas le rejeter, votre monde serait nul." - Anders Hejlsberg
Mason Wheeler
1
const est également un modificateur de type C et a été depuis la première norme ANSI C.
Huperniketes du
Étant gâté par Java / C #, je suis un type paranoïaque qui aime laisser des affirmations toutes les chances que j'obtiens. Ce qui peut mal tourner va mal. S'il y a une assistance à la compilation ou à l'exécution, alors comptez-moi! Je suis devenu converti dès que j'en ai entendu parler 3-4 fois, et j'ai suivi une partie de ce lien (assez pour voir la syntaxe, je n'ai pas eu besoin de lire pourquoi): possibilité.com / Cpp / const.html Juste parce que quelque chose n'a pas encore explosé sur mon visage ... ça prend peu d'efforts pour être const correct, et ça ne fait pas mal. Découvrez les pensées de Joel: joelonsoftware.com/articles/Wrong.html
Job

Réponses:

28

Eh bien, je n'ai pas été convaincu jusqu'à ce que j'essaie d'adopter la philosophie.

J'ai d'abord commencé par mettre constà la disposition des membres vraiment en lecture seule les arguments de fonctions et de membres de classe les plus élémentaires.

De là, je ne pouvais plus compiler. Ensuite, j'ai persévéré à aller dans le code en utilisant ces classes de base, voir si les constajouts précédents étaient vraiment légitimes par rapport à l'utilisation que j'en faisais. Cela m'a aidé à corriger certains bugs en cours de route en ajoutant de la constance à d'autres parties du code.

C'est contagieux. La plupart du code a encore plus de constance et j'ai trouvé plus facile à déboguer car cela vous donne confiance que le compilateur vous arrêtera si vous commencez à modifier quelque chose que vous ne devriez pas.

Une fois que l'application a été exécutée à nouveau, elle a été plus rapide (a dû changer certains algorithmes que j'ai découverts n'étaient pas adaptés au travail), avec beaucoup moins de bogues et plus faciles à comprendre lors de la lecture du code.

J'étais convaincu.

Maintenant, je pense que c'est encore mieux lorsque vous utilisez beaucoup d'assertions en plus de constness, car cela vous donne confiance lorsque vous devez écrire du nouveau code ou modifier le code actuel. Vous savez que le compilateur vous arrêtera si nécessaire. Cela vous permet d'oublier d'avoir à vérifier tout ce que vous ne devez pas modifier, puis vous disposez de plus de temps pour réfléchir à une réflexion plus spécifique à l'entreprise ou à une réflexion architecturale.

Klaim
la source
8
+1 pour contagieux, ce qui signifie essentiellement que vous devez soit devenir un const const, soit l'éviter complètement.
Martin Wickman
Vous devez également ne pas compter sur des bibliothèques qui ne font pas l'exactitude de const. Votre approche ne fonctionne pas lorsqu'elle signifie que vous ne pouvez appeler aucune des fonctions de l'interface graphique car elles ne sont pas const - ou vous devez la rejeter à chaque appel de l'interface graphique.
Martin Beckett
4
+1 pour "j'ai trouvé plus facile à déboguer", j'utilise constmême pour une variable locale que je sais que je n'aurai pas besoin de changer, de cette façon lors de la lecture du code je peux survoler a ifou a forou quoi: ma variable est une constante, je sais que ça ne changera pas! Je ne me soucie pas des optimisations, mais j'ai un cerveau limité, et quelques niveaux de retraits + const-correctness aident grandement!
Matthieu M.
@MatthieuM .: Avez-vous déjà envisagé de passer à Haskell? ;-)
Giorgio
@Giorgio: Je l'ai exploré, allant même jusqu'à acheter "Real World Haskell". Pour être honnête, je ne suis pas ravi de la paresse par défaut et des nombreux opérateurs cryptiques qui ont vu le jour.
Matthieu M.
15

Je n'ai jamais été un partisan de la programmation orientée objet, et si je me suis développé moins, j'en apprends davantage sur la programmation en général. Comme je l' ai étudié différents paradigmes de programmation, je me suis rendu compte que immuabilité est l' un des les concepts centraux de la conception des programmes, ce qui affecte le logiciel écrit selon toute philosophie. C'est extrêmement important dans la programmation fonctionnelle, avec des implications dans l'optimisation et la concurrence en plus des garanties de sécurité simples.

Fondamentalement, tout ce qui peut être immuable devrait probablement l' être, sauf si vous avez une bonne raison pour un état mutable. D'après mon expérience, l'écriture de programmes dans n'importe quelle langue pour atteindre cet objectif conduit à un code plus sûr et meilleur . Vous n'avez rien à perdre en utilisant le constcas échéant - l'immuabilité est gratuite!

(Par ailleurs, j'ai joué avec l'idée de créer une fourchette de GCC pour un dialecte de C ++ dans lequel tous les types sont constsauf si explicitement qualifiés de mutable. S'il y a un support pour une telle chose, je m'engagerai totalement à le maintenir et à l'utiliser.)


D'un point de vue OO, l'immuabilité impose l'encapsulation en empêchant l'accès en écriture illimité. Il réduit le couplage entre les classes car les objets immuables doivent gérer pleinement leur propre état et donc se comporter comme des valeurs ordinaires. La correction des constances facilite considérablement le processus de vérification de la correction des programmes, en particulier dans le contexte d'une programmation simultanée. Avec la référence sémantique C ++ et la sémantique de référence rvalue C ++ 0x, vous pouvez utiliser des objets immuables sans vous soucier de la surcharge de les copier partout. De plus, le compilateur peut fonctionner avec une magie d'optimisation assez incroyable si vous travaillez avec des objets principalement immuables.

Je sais que ça craint de taper constpartout, mais on s'y habitue rapidement, et les avantages deviennent apparents au fil du temps en termes de fiabilité et de maintenabilité. Je ne suis pas un brillant écrivain, et cela semble être une tâche difficile avérée de le prouver, mais je sais que l'exactitude de la const m'a été extrêmement utile en tant que développeur lors de la conception et de la mise en œuvre de programmes, et je pense que l'expérience est le meilleur professeur à cet égard.

Jon Purdy
la source
2
Vous avez simplement dit que l'exactitude de la const est une bonne chose. Vous avez dit que cela "conduit à un code plus sûr et meilleur". Peux-tu dire pourquoi?
David Reis
Je suis totalement dans le camp d'immuabilité, ma langue préférée est Erlang. Mais je dirais que l'immuabilité via const en C ++ n'est pas vraiment gratuite. Il y a des inconvénients comme du code moins lisible, des versions const et non const de la même méthode, ou la suppression de const car "il n'y avait tout simplement pas d'autre choix".
grok
1
Je vous conseille de ne pas simplement l'utiliser mutable, car il a une signification claire en termes de constance. Cela signifie que cet objet de données peut changer d'une manière qui n'affecte pas le comportement de l'objet et permet des choses comme la mise en cache des réponses. Inventez un autre mot-clé.
David Thornley
2
@David Thornley: Par souci de cohérence, mutablec'est le choix logique. void alter(mutable Point&)n'a pas de sens, comme c'est le cas mutable int foopour une variable locale, et ni l'un ni l'autre de ces conflits avec la langue existante ou l'utilisation existante de mutable. En outre, Object mutable* mutablesemble assez effrayant pour être un avertissement sur la nécessité ou la correction.
Jon Purdy
Si vous faites la fourchette, envisagez plutôt d'utiliser CLang - cela devrait être moins douloureux.
gf
6

L'avantage de la correction constante est qu'elle impose une discipline au programme et facilite le raisonnement sur certaines parties du programme.

La discipline est que vous devez savoir où quelque chose pourrait changer. L'avantage correspondant est qu'il est plus facile de voir ce que fait un morceau de code lorsque vous pouvez savoir ce qui pourrait changer l'état.

David Thornley
la source
1
"Les programmes doivent être écrits pour que les gens puissent les lire, et accessoirement pour que les machines s'exécutent." - Abelson & Sussman, SICP
Brandon DuRette
4

Être const correct souligne la justesse de la conception que je traite près d'un problème similaire qui n'utilise pas d'opérateurs de distribution; donc ne pas utiliser cast et être const correct, utilisation minimale de mutable - tous ces éléments sont des pointeurs pour mesurer la qualité de la conception mais pas les outils réels pour résoudre le problème global en main.

PS: j'ai été totalement convaincu constune fois que j'ai compris la justesse de son utilisation;)

legends2k
la source
2

Je vois deux principales raisons d'écrire du code const-correct. La première est que le compilateur est votre ami, et en utilisant const vous le laissez vous avertir des bugs potentiels. La deuxième raison est que const-correctness rend le code plus lisible. Par exemple, vous savez toujours quels arguments de fonction sont des entrées et lesquels sont des sorties. Vous savez également quelles fonctions membres modifient l'objet et lesquelles ne le font pas. Vous savez ces choses instantanément sans avoir à lire le code. Cela suppose, bien entendu, une utilisation très judicieuse de const_cast.

Dima
la source
2

J'étais converti dès que j'ai su que c'était possible. Cela avait du sens pour moi du point de vue d'un «bon style de programmation». Il y a plusieurs raisons pour lesquelles il est bon d'être constant:

  • Lisibilité et compréhension. Si je lis le code de quelqu'un d'autre et qu'une fonction prend une référence const comme paramètre, je sais que le paramètre est uniquement destiné à être utilisé comme une variable en lecture seule. Il s'agit d'une victoire massive, surtout si le code est un environnement multi-thread.
  • Le compilateur peut utiliser le qualificatif const pour faciliter ses passes d'optimisation.
  • Disons que j'ai un objet de classe A dans une situation où je ne veux pas qu'il change. Ensuite, les seules fonctions membres qui peuvent être appelées pour cet objet sont celles qui sont const.
sashang
la source
2

Pour résumer deux points qui ont été traités dans d'autres réponses et en ajouter un nouveau:

  • constdocumente le code aux utilisateurs de votre API. Il forme un contrat entre une fonction et son appelant, que la fonction ne modifiera pas ses paramètres. (Veuillez noter que const_castcela ne permet pas à une fonction de changer son paramètre, il permet de passer ce paramètre à d'autres fonctions qui ne modifient pas leurs paramètres mais ont oublié l' constannotation.) Il est également utile dans les fonctions / boucle / etc. car il aide à comprendre beaucoup le de la même manière qu'un invariant de boucle.

  • constdocumente votre intention au compilateur. Il est toujours préférable de trouver des erreurs au moment de la compilation que d'attendre l'exécution de ce morceau de code.

  • constest nécessaire pour le polymorphisme sûr de type. Les pointeurs (sous toutes leurs formes, pas seulement les pointeurs bruts) ne sont covariants que s'ils le sont const(Remarque: ce n'est pas la même chose que "pointeur vers const"). La covariance nécessite une interface en lecture seule et la contravariance nécessite une interface en écriture seule.

Le deuxième de ceux-ci, je l'ai appris en premier. J'ai commencé avec constuniquement sur la cible des paramètres de pointeur et de référence, jusqu'à ce que je commence à voir les avantages de détecter les erreurs plus tôt, et de commencer à l'utiliser sur les locaux, etc.

Ensuite, j'ai appris que la plupart des #defines peuvent être remplacés (en C ++) par des constantes globales, avec des avantages supplémentaires de sécurité de type. Je l'ai donc utilisé là aussi.

Enfin, j'ai suivi un cours sur les systèmes de types et le calcul lambda, et j'ai appris que les constnon- consttypes sont fondamentalement différents (car ils prennent en charge différentes opérations), et depuis lors, je n'ai même jamais envisagé d'écrire du code C ++ sans une utilisation intensive de const.

Ben Voigt
la source
1

Voici mes 5 cents de ce que je n'ai pas vu d'autres mentionner. Lorsque vous passez des variables, vous ne voulez pas passer par valeur, sauf si vous en avez vraiment besoin, pour éviter des constructions, des destructions et des copies supplémentaires. Donc, à moins que vous ne deviez vraiment passer par la valeur, utiliser des références partout, même si vous ne voulez pas changer la valeur passée, c'est une augmentation significative des performances. Pour cette raison, lorsque vous avez des fonctions prenant des références de tous ses arguments, vous devez faire savoir à l'appelant ce que la fonction ne modifiera pas.

C'est le même principe, mais je voulais juste ajouter une raison pratique d'utiliser const.

Nikiforos Rotas
la source