I found myself in a quite blaspheme position of
wondering how much in my personal experience
const-correctness really helped me, and how much
did it cost me.
I'm not questioning if the const-correctness concept is
consistent or correctly captured by the C++ syntax (that
could be another interesting discussion), but only if
on the field it actually pays off.
IMO a software shouldn't represent all aspects of a
problem, but only aspects for which the description and
handling cost is justified by a return.
In this very moment I try to think to a single case
in which const-correctness helped me, saving me
from writing a logically inconsistent statement (of
course saving from a logically inconsistent statement
in which the logical error only is inherent
const-correctness doesn't count as a case).
Oddly enough my selective memory doesn't bring a single
case... I'm not telling it's rare... I can't actually
remember just one very single case in which a
const-correctness-related error message was useful
to anything else than const-correctness itself.
Other than me there's the compiler... after all const
correctness add details to the specifications of what
is being implemented. However const correctness of
references and pointers is never an help to a compiler
in C++, as only binds the reference and the pointer,
not the object, and it's perfectly legal to force that
aspect (and compilers are required to be paranoid on
this possibility). Note that I'm talking about const
correctness, not constness of objects that surely
help a lot both compilers and programmers.
I know many thinks the opposite on this point... for
a description of this aspect from a more recognized
voice see http://www.gotw.ca/gotw/081.htm
Hence so far in my experience the return value is a
desolate zero. No help for me, no help for the code
generator.
On the other side IMO the cost of const-correctness is
high... actully I would say very high.
Description gets more complex, with more cases.
In a few areas you get into serious trouble (iterators).
You get added freedom (calling a method with a reference
may open a window, calling it with a const reference
can save a file), but i'm not sure this is good.
Makes the language harder to teach (that's also because
of powerful but complex C declaration syntax, I know,
but a justification doesn't make it easier).
In my experience since the introduction of STL is probably
the source of most substantially useless (remember I'm
not counting useful a message about const-correctness
itself) and cryptic error messages.
I suppose its cost is relatively high in compilers too
(just a gut suspect, however; I never wrote a compiler
supporting the const correctness concept) and in libraries.
Do people here more expert than me (I seriously approached
C++ only a few years ago) have a very different view on
this ? May be const correctness has been found helping
in very large software projects with a large number of
programers ? That's a world I don't have any experience in.
I'm not looking for a description of why in theory it's
an help, but on when it actually helped in developing
complex software. Here we're going to start with a kind
of big C++ software project, and I'm not sure if insiting
on const correctness is a good thing or if we should just try
to learn how to get our code compiled by annoying compilers.
Just going for const correctness is of course the easy
choice (and no one could probably blame me for proposing
that); but is it really a *proven* good choice ?
A somewhat confused Andrea
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
> Do people here more expert than me (I seriously approached
> C++ only a few years ago) have a very different view on
> this ? May be const correctness has been found helping
> in very large software projects with a large number of
> programers ? That's a world I don't have any experience in.
"More expert than you" is unlikely, but yes, I find const-correctness
helpful. The most obvious way it is helpful is simply in communication
of intent.
If I'm reading a piece of unfamiliar code and trying to work out what it
does, a lot of my effort is concentrated on working out, for each
variable I see, what things affect the value of that variable. If the
variable is global, I'm screwed. If the variable is local, and declared
half-way down the function instead of the top, I have to inspect half a
function. But if it's const, that cuts out all the code but one line.
Thus, the more variables I can make const the better, which is why I
swear at code involving member functions I want to use that could be
const but aren't.
Emily.
> Other than me there's the compiler... after all const
> correctness add details to the specifications of what
> is being implemented.
Details details details. The more details the better, because
then intent is clearer.
Making methods const means that one can call a method on the
object and know[1] that the object's state isn't going to change.
Functions taking const references are nice because then you can
call a function and know that your object isn't going to change.
This also necessitates the constness of member functions.
So I don't know that constness helps me program correctly, but it
helps me know what to expect when working with other people,
passing my objects to them or calling their methods.
> Hence so far in my experience the return value is a
> desolate zero. No help for me, no help for the code
> generator.
Are you working with others? Do they attempt to code with const-
correctness in mind? Just curious, but I am a dogmatic in this
one; I make everything const that I can and cry when I need to
make things non-const. It just feels nice to have a const object
that you can know isn't going to change.
> I'm not looking for a description of why in theory it's
> an help, but on when it actually helped in developing
> complex software.
Yeah I couldn't say that it's necessarily made the code any
better, but it does help the piece-of-mind. :)
[1] - Except in the case of mutable members, but those changes
shouldn't be visible from the outside.
-tom!
> I found myself in a quite blaspheme position of wondering how much in
> my personal experience const-correctness really helped me, and how
> much did it cost me.
The question is somewhat ambiguous. Given the language specification,
you are almost required to be const correct in a number of situations; a
temporary will only bind to a const reference, not to a non-const one.
So if you write T& as the type of a parameter, the client code cannot
pass a temporary to the function. Given that, coherency then argues for
being const correct everywhere. So you don't have a choice.
If the question is rather, why is the language so defined to require
this, the answer is that it the alternative was tried, and found to be
error prone. My intuitive feeling (read: I really don't know what I'm
talking about, but I'm going to say it anyway) is that this (the error
prone-ness) is really only true when implicit conversions are involved.
If your code only uses user defined types with no implicit conversions
(which is the case for most of my code), the restriction that you cannt
bind a temporary to a non-const reference is more a problem than a
solution. The experience which led to the contrary conclusion was from
the earlier days of C++. I suspect that use of built-in types was much
more frequent then, and they certainly didn't have explicit to prevent
implicit conversions to user defined types. Times change, and what was
(probably correctly) felt to be necessary then may be more of a problem
now.
In my own code, I insist on 100% const correctness for value objects;
anything less, and I consider the code incorrect. For entity objects
(where I'm only passing pointers or references to explicitly created
objects), I'm much less careful. I generally strive for const
correctness on the grounds of orthogonality, but I don't worry about it
if I miss a function or two, and anytime I'm unsure of the long term
evolution of the function, I'll drop the const, even if the function
could currently use it.
And of course, I do what is necessary when working with an existing code
base. In the project I'm currently working on, const was pretty much
ignored in the entity objects. I do likewise, because making just one
part of the program const correct is a pain, and doesn't work. If I
declare my function to take a const reference to an object, because it
doesn't change the value of the object, I'm suddenly stuck that I cannot
call logically const functions on the object in my function, because
logically const or not, they weren't declared const in the existing
code. So the code is not const correct. I don't let it bother me.
--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
Surely these statements are inconsistent. The cost can only be high if
we are faced with a lot of code that isn't const-correct. Since the
standard library is already correct, and operating system headers are
mostly correct, and after so many years of const in the language I
presume that even legacy code is mostly correct, that implies that
someone is churning out non-correct source code.
It's probably me. I'm a lousy typist. Fortunately, const lets the
compiler correct most instances of that particular kind of typo. Perhaps
you have lived with const for so long that you can no longer even think
the kind of mistake that it saves the rest of us from making. I'm sure
people have argued that modern compilers no longer benefit from
structured control and so we should all go back to using "goto". Perfect
programmers probably could.
What about the case where you are passing something by reference to
avoid copy costs? In this situation it is very helpful to be able to
differentiate code which may change that something from code which may
not. The cost is only to type const in the parameter list. The
benefit is that both the caller and the compiler know the intent, and
the compiler can help enforce that intent. Any time you can express
your intent in a way that the compiler can enforce it is more likely
that your intent will not be violated. Not impossible, of course, but
definitely less likely.
Simple example: You have a sequence of records read from a database.
You can grant multiple threads read-only, i.e., const, access to this
sequence, but only const will tell you if this is safe or not.
Another simple example: You have a class that returns a pointer or
reference to some internal data. Without const that class cannot know
whether the caller who obtains the pointer or reference will modify
that data or not. It can be both safe and appropriate to allow
external read access to internal data, but allowing external write
access to internal data can be much messier and harder to justify.
Without const how would you deal with this situation?
Finally, const allows the compiler to make assumptions that it
otherwise could not. If you pass a pointer or reference to const to
some function, the compiler, and the optimizer, may assume that
function does not change the object referred to.
Don't blaspheme. const is a very Good Thing! :-)
Randy.
Stone him!
> [...]
> In this very moment I try to think to a single case in which const-
> correctness helped me, saving me from writing a logically
> inconsistent statement (of course saving from a logically
> inconsistent statement in which the logical error only is inherent
> const-correctness doesn't count as a case).
The question is, *do you think about const-correctness when
writing code*? If so, it may simply be that your awareness of
constness is automatic, and so const-correctness is encouraging
a good style of coding to begin with. The compiler warns me if
there is unreachable code. I almost never see this warning. Does
that mean that the effort spent by the compiler vendors to
implement this diagnostic is wasted? No, it just means that I
already write my code in such a way that does not trigger the
diagnostic.
As others have noted, the true test of const-correctness is A)
when you have to use someone else's code, or B) someone else
has to use yours. If you asked other people to use your code,
and it lacked const correctness, you might find them using it in
incorrect ways. Another area where I find const correctness
invaluable is in migrating legacy C code (which often lacks
const correctness in a big way). Since many things are much
less encapsulated in old C code, it is often difficult to tell where
things get changed, and how. I find that it's much easier to
abuse such code unwittingly, because it's too much of a hassle
to find all the places where data can get changed.
Also, if I see a function that I think ought to be const, or have
const params, and it doesn't, I am suprised, and take a closer
look. This is often a warning that the function does not do
what I think it does, or has side effects that I wouldn't expect.
Again, with code you write entirely yourself, this is probably
not an issue. But with library code, or working with someone
else's project, these are very common issues, I think.
> [...]
> In my experience since the introduction of STL is probably
> the source of most substantially useless (remember I'm not
> counting useful a message about const-correctness itself)
> and cryptic error messages.
I think the problem of error messages is independent of const
correctness. And I agree that it's a big and growing problem.
I've seen code that literally generates 5-10 screen fulls of text
for just one error message. I'm aware that there are tools to
cope with that, but it would be nice if compilers integrated
such features directly.
> [...]
> May be const correctness has been found helping in very
> large software projects with a large number of programers ?
> That's a world I don't have any experience in.
> [...]
Even if it's not a large project, if it's a strange project, the
const correctness helps use the code properly. I don't see it
as being any different from data hiding. They are both
compiler-enforced restrictions on how you access data. When
was the last time you got a warning that you were trying to
access private data? Again, that's something that tends to
come automatically, and so if you use it, you don't think about
it. Try writing code that is *not* const-correct, and come back
to it in 6 months and see how you use it. ;)
Dave
"Andrea Griffini" <agr...@tin.it> wrote in message
news:3deee55...@news.tin.it...
>
> In this very moment I try to think to a single case
> in which const-correctness helped me, saving me
> from writing a logically inconsistent statement (of
> course saving from a logically inconsistent statement
> in which the logical error only is inherent
> const-correctness doesn't count as a case).
>
> Oddly enough my selective memory doesn't bring a single
> case... I'm not telling it's rare... I can't actually
> remember just one very single case in which a
> const-correctness-related error message was useful
> to anything else than const-correctness itself.
Hello Andrea,
Yes I've had the same experience. Const correctness has added
nothing but hassle to my C++ programs without any visible benefit,
although I guess the compiler might be making use of it for
optimisation purposes?
Programs evolve and change constantly, and the const correctness
handicaps this process by it's insistent ripple-through behaviour.
Another thing that really bothers me is const member functions!
I want to be able to change a classes implementation without altering
its interface, so if a member function that was const, now becomes
non-const, (eg if I add caching) why should clients care? It just breaks
the interface!
So I don't use const member functions, not only are they a hassle to
maintain, they are logically flawed!
I don't suppose anyone agrees do they? :-)
Kind Regards,
Mark Jordan.
> Hello...
>
> I found myself in a quite blaspheme position of
> wondering how much in my personal experience
> const-correctness really helped me, and how much
> did it cost me.
[snip]
I think it was coding in Java that taught me the value of const Foo*,
const Foo&, etc. While programming in Java I have occasionally
found myself tracking down some bug or other that occured becase I
passed a reference to a function, and that function modified
the referenced object when I didn't expect it.
In 2 different medium-sized C projects that I helped convert to C++, I
saw C++'s stricter const reveal the cause of several long-standing
bugs.
const-correctness also supports design idioms such as COW.
> Do people here more expert than me
[snip]
I think I'm less expert than you are.
> but is it really a *proven* good choice ?
[snip]
I think there is lots of anecdotal evidence. What we don't have is
measuremnts from carefully designed experiments. (So far as I
know, that is.)
>> On the other side IMO the cost of const-correctness is
>> high... actully I would say very high.
>
>Surely these statements are inconsistent. The cost can only be high if
>we are faced with a lot of code that isn't const-correct.
With more cost I mean that enforcing const-correctness
implies more typing, more thinking, and even duplication
of methods (just to provide a const version that does
basically the same but returns a const-something).
Also const-correctness on things like iterators has
other drawbacks (a const_iterator of course is not a
const iterator, like a pointer to a const is not a const
pointer, but conversion between iterators is way harder
than between pointers, and in some case iterators
- and not const_iterators - are required even when
logically a const_iterator should have been sufficent).
>Perhaps you have lived with const for so long that you
>can no longer even think the kind of mistake that it
>saves the rest of us from making.
Really compiler enforcement of const correctness saved
you from making logical errors ? That never happened
to me... but I can take your word.
I find more reasonable Tom Plunket position that is
that the *reading* of const-correctness related keywords
help humans and make things easier to understand.
Good naming and commenting should do the same, however.
>I'm sure people have argued that modern compilers no
>longer benefit from structured control and so we should
>all go back to using "goto".
>Perfect programmers probably could.
I don't think that structured programming was ever thought
as helping compilers. Actually one of the first things
many optimizing compilers do on your nice structured source
is chopping it in a lot of pieces and drawing a spaghetti
bowl of goto arrows between them.
Stuctured programming and its enforcement by the compiler
is an help for humans.
My doubt about const correctness is that I never found
compiler enforcement being really an help. I'm glad the
compiler informs me I forgot a closed brace or that
the "else" I typed is nonsense ... but when it tells
me that I can't call that method because i've only a
const reference as far as I can remember the error always
was just in const-ness of the parameter or of the method
declaration (and never that I was calling the wrong method
or i was calling it on the wrong object).
In other words I always found const-correctness only
helping const-correctness.
Andrea
>So I don't know that constness helps me program correctly, but it
>helps me know what to expect when working with other people,
>passing my objects to them or calling their methods.
That's a good point. Probably discipline with names and
comments should suffice, but I may agree that having
that enforced may help.
In other words const-correctness enforcement helps only
because you're forced to type const-correct comments,
and those are the real value. They help you *before*
you start typing in statements...
> > Hence so far in my experience the return value is a
> > desolate zero. No help for me, no help for the code
> > generator.
>
>Are you working with others? Do they attempt to code with const-
>correctness in mind? Just curious, but I am a dogmatic in this
>one; I make everything const that I can and cry when I need to
>make things non-const.
We're a quite small group, and rarely anyone has to interact
with other people's code, except for a quite specific an
narrow interface. We're also so few that we directly decide
interfaces discussing them and we never discover them
just reading a doc or an header file.
And ... ahem... (blush) no. Most code isn't currently
const-correct at all. The background is C, where you
can just ignore almost completely the issue.
Andrea
>The cost is only to type const in the parameter list. The
>benefit is that both the caller and the compiler know the intent, and
>the compiler can help enforce that intent. Any time you can express
>your intent in a way that the compiler can enforce it is more likely
>that your intent will not be violated. Not impossible, of course, but
>definitely less likely.
This is exactly what I was not sure about.
Communicating or decyphering the intent with
just the part of the .h file that a compiler
understands has never happened to me, as
always there were man pages, comments, a
document or even a talking person describing
me the intent.
After some thought I think that I was missing
this value of const correctness ... and the
compiler enforcing it is in that no different
than a window requiring a dscription of changes
after checking in a module, or requiring
justification after discovering a naming
style violation.
>Without const how would you deal with this situation?
With comments and description ... if I want to.
Or I may have the choice of not doing it if I
don't want to invest that money.
I was also forgetting that ignoring the issue can be
really dangerous if you've conversion constructors
or implicit conversion operators, because copies can
be obtained and passed to functions without intention.
May be const-correctness would have not been so important
for C++ with foresight of implicit conversion problems
and having "explicit" keyword from the beginning.
>Finally, const allows the compiler to make assumptions that it
>otherwise could not. If you pass a pointer or reference to const to
>some function, the compiler, and the optimizer, may assume that
>function does not change the object referred to.
I don't agree... I don't think the optimizer can assume
anything. Remember that a const reference doesn't
tell *anything* about const-ness of the referenced object,
but only about operations allowed using *that* reference:
there may be total or partial aliasing and even const-casting.
So:
- Calling a const method doesn't imply the
object won't change.
- Passing a const reference doesn't mean the
object won't be changed (even if the object
is local and no-one else knows its address...
const-casting is legal and must work if the
referenced object is not a constant object).
- Receiving a const reference doesn't mean
that during the funcion others won't change
the referenced object.
It's perfectly legal receiving in the same function
a const reference A and a non-const pointer B where
B points to a sub-object of A... so after any change
made using B the compiler must consider that A may
have been changed.
Every time any unknown code is executed all objects
referenced by const references you received may
potentially change state... so after every constructor
call for which the definition is not known, even
every call to builtin operators line new or delete
means that all no assumption about referenced object
state is possible.
Andrea
>...
>In this very moment I try to think to a single case
>in which const-correctness helped me, saving me
>from writing a logically inconsistent statement (of
>course saving from a logically inconsistent statement
>in which the logical error only is inherent
>const-correctness doesn't count as a case).
>
>Oddly enough my selective memory doesn't bring a single
>case... I'm not telling it's rare... I can't actually
>remember just one very single case in which a
>const-correctness-related error message was useful
>to anything else than const-correctness itself.
>...
It's difficult to be very precise since you do not define
what you mean by "const correctness".
Assuming you're talking about applying the keyword "const",
here are some thoughts:
1) Const variables of simple type.
Always helpful to the programmer and/or the compiler,
and furthermore, failure to apply const (e.g., a "char*"
where there should be "char const*") makes for a very
difficult life. Should be adhered to religiously.
If there *can* be a "const", there *should* be.
2) Const return value for a function.
Generally an abomination (the new wisdom after Mojo).
3) Const methods to support client using const on object.
Sometimes helpful, sometimes not, a bit of a nuisance to
have a const duplicate of all relevant methods. In my
experience it's best to be very pragmatic about this. It
is a language defect at a higher level than mere syntax.
4) Const object that gives access to non-const object.
I've never figured out what's "right" or even "practical"
here. Talking about "const correctness" in this context
is probably futile. Talking about this situation in
general, instead of a single concrete example, is probably
futile at the current time.
5) Object with const non-static data member.
An abomination unless assignment is disallowed, and should
be avoided anyway.
Well, okay, fire up the discussion engines... ;-)
Cheers,
- Alf
Almost certainly you are still using a C mindset. It is actually almost
impossible to write C++ using the full range of tools provided by the
Standard Library without taking note of const correctness.
The ripple through effect is poison in C because of its lack of function
overloading (functions such as strtok() cannot be implemented in a const
correct form in C) However in C++ the ripple through is exactly what we
want to ensure that we do not abuse data.
>
>Programs evolve and change constantly, and the const correctness
>handicaps this process by it's insistent ripple-through behaviour.
If your code evolves in ways that cause unexpected ripple through of
const then I suspect that there is a problem in the design that the
evolution is addressing.
>
>Another thing that really bothers me is const member functions!
>I want to be able to change a classes implementation without altering
>its interface, so if a member function that was const, now becomes
>non-const, (eg if I add caching) why should clients care? It just
breaks
>the interface!
We have to use the language correctly. A function should not be declared
const simply on the basis that it does not change the object, but on the
basis that it would be conceptually wrong for it to change the logical
state of the object.
Sometimes certain aspects of an object's physical state (such as cached
results) need changing even when the object is being used in a logically
const context. That is what mutable is for.
>
>So I don't use const member functions, not only are they a hassle to
>maintain, they are logically flawed!
No they are not but a misunderstanding of the design concepts may make
it look that way.
>
>I don't suppose anyone agrees do they? :-)
Oh, you will have some agree but I would be amazed if any of those are
among those who are considered to be experts on C++ programming. If you
wish to argue with the likes of Scott Meyers, Herb Sutter, Andy Koenig,
Bjarne Stroustrup etc. you will have to marshall your arguments very
carefully.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
That's what 'mutable' is for. If you add caching, the member function is
conceptually still const, i.e. it doesn't change the observable state of
the object.
> So I don't use const member functions, not only are they a hassle to
> maintain, they are logically flawed!
So how do you call member functions on const references?
-- Niklas Matthies
>The question is, *do you think about const-correctness when
>writing code*? If so, it may simply be that your awareness of
>constness is automatic, and so const-correctness is encouraging
>a good style of coding to begin with.
This is a good point on the lines of what Tom Plunket said.
>The compiler warns me if there is unreachable code. I almost
>never see this warning. Does that mean that the effort spent
>by the compiler vendors to implement this diagnostic is wasted?
>No, it just means that I already write my code in such a way
>that does not trigger the diagnostic.
I'm not sure that warning is active with C++ ... a lot
of template trickery ends up in unreachable code.
Another warning on that level is the "not all paths return
a value" ... and actually I'm dubious about that.
The compiler isn't smart enough to understand that in some
cases the missing "path" can never be taken and this
generates spurious warnings on my builds (and they're in
<algorithm>... so I'm a bit reluctant in modifying code
coming with the compiler to fix that). On the other side
I can remember that warning saving me may be only a couple
of times in my life.
Of course may be things are of course different with who
is learning the language or even programming (and was crazy
enough to choose a monster like C++ to learn programming).
>As others have noted, the true test of const-correctness is A)
>when you have to use someone else's code, or B) someone else
>has to use yours. If you asked other people to use your code,
>and it lacked const correctness, you might find them using it in
>incorrect ways.
Yeah. As I said in my experience I was lucky enough of
never having just an uncommented ".h" to guide me.
>Another area where I find const correctness invaluable is in
>migrating legacy C code (which often lacks const correctness
>in a big way).
In C you can simply ignore the issue and all your code
will probably compile fine. Things with C++ are different
because of temporaries.
>Since many things are much less encapsulated in old C code,
>it is often difficult to tell where things get changed, and how.
>I find that it's much easier to abuse such code unwittingly,
>because it's too much of a hassle to find all the places where
>data can get changed.
True... but is this really related to const-correctness ?
I would say no.
>Also, if I see a function that I think ought to be const, or have
>const params, and it doesn't, I am suprised, and take a closer
>look. This is often a warning that the function does not do
>what I think it does, or has side effects that I wouldn't expect.
Or that the prototype was simply wrong about that
issue. No const correctness and it would have been
correct and you wouldn't have spent time on that.
In my experience this is the most frequent case.
>I think the problem of error messages is independent of const
>correctness. And I agree that it's a big and growing problem.
STL error messages are a known problem... and a few
solutions are facing. I was trying to say that most often
when I make such an error it's something related to
const-correctness. Things get tricky with const-correctness
and iterators.
Note that there are parts of STL I really don't use... so
may be that the fact that most errors are const-correctness
related in my experience is skewed by the fact that I'm
not fighting with binders and their friends.
>Even if it's not a large project, if it's a strange project, the
>const correctness helps use the code properly. I don't see it
>as being any different from data hiding.
Ok... you brought this out. My very first C++ real project
was a 50+Klines module for our CAD/CAM system. It uses just
a subset of C++ that I found later described as "C with classes"
and (please don't scream) everything is public! Moreover,
honestly, I didn't find the need for making things private.
I wrote it myself alone... so probably this doesn't count.
>They are both
>compiler-enforced restrictions on how you access data. When
>was the last time you got a warning that you were trying to
>access private data? Again, that's something that tends to
>come automatically, and so if you use it, you don't think about
>it. Try writing code that is *not* const-correct, and come back
>to it in 6 months and see how you use it. ;)
Hmmm. I think you're right on this. Adding data hiding to
that project now is probably a suicide.
In the begining everything is clean ad nice even without
compiler enforcement... but as you get near the result
and deadlines are approaching the temptation is high,
especially (this is what I've read) if you're working alone.
I think I'll try making what should be private actually
private on that project... just to have some laugh on
the number of errors the build will generate :)
Andrea
>although I guess the compiler might be making use of it for
>optimisation purposes?
No. Const-correctness can never help the optimizer.
The reasons are the presence of aliasing (and no
available method to inform the compiler that
aliasing should not be considered) and the fact
that casting away const-ness from a reference is
perfectly legal and must be supported.
>Programs evolve and change constantly, and the const correctness
>handicaps this process by it's insistent ripple-through behaviour.
This is something I've heard and on which I agree...
trying to add const-correctness late is terribly costly.
Our projects now don't consider const correctness beyond
what you're forced to by the language... I was wondering
if would be better for us to steer on what is in current
literature The Right Thing for *next* project.
I'm quite positive it's not a good idea to invest in fixing
const-correctness on current ones.
>Another thing that really bothers me is const member functions!
>I want to be able to change a classes implementation without altering
>its interface, so if a member function that was const, now becomes
>non-const, (eg if I add caching) why should clients care? It just breaks
>the interface!
This is the same that James Kanze said... sometimes updating
a method changes it from being const to being non-const
and this breaks a lot of existing code.
This never happened to me, but I can imagine such a situation.
I wonder if anyone used with C++ the approach described in
Object Oriented Software Construction of having only queries
(not changing the state and returning a value) and commands
(not returning a value but changing the state). That approach
looks even more stringent than const or non-const and is
more a directive on how to build interfaces (like structure
programming forces you in the way you can use jumps)...
C++ const-correctness doesn't gives you a direction... looks
like just an exercise in attention. Other parts of C++ give me
the same impression... like when I've to type
for(std::map<std::string,int>::const_iterator i=m.begin(),e=m.end();
i!=e; ++i)
...
instead of
for(m::const_iterator i=m.begin(),e=m.end(); i!=e; ++i)
...
This IMO is a typical case in which no real thinking is required,
and just a possibility of an annoying meaningless error is added.
Redudancy isn't always bad, of course. For example requiring
you to fill in your account number AND your name AND your
address when making a deposit is a security... without that
redudancy making an error when reading the account number
would automatically mean redirecting the money on a different
account and that's bad (ok... just for a moment imagine this
is not what indeed happens ;) ).
I just do not happen to remember a single case in which
compiler enforcement of const-correctness or the
necessity of re-entering the whole type actually helped
me in discovering a true logical error.
On the contrary I remember a deposit of mines that took
three weeks to get on my bank account even if cheque
was indeed resulting deposited because probably there
was something wrong either in what I wrote or in what
they read... and all that redundancy (that I thought
being good) was simply ignored.
>So I don't use const member functions, not only are they a hassle to
>maintain, they are logically flawed!
>
>I don't suppose anyone agrees do they? :-)
hey :) ... my position wasn't "const-correctness is a bad joke!",
but "what do you guys really think of const-correctness ?".
It's just a point on which my personal (little) experience
doesn't seem to agree with what I found in the literature.
Don't count me on your side (for now) ;)
Andrea
A const member function can't just suddenly change to a non-const one.
Clients indeed should care if a member function is const or not.
Const assures that the function doesn't change the object (at least as
far as the clients can see it). Adding a cache system to a const function
doesn't really change the object (only speeds it up) so the function
should still be const.
There's a mutable keyword for this purpose. Stick a mutable to your
cache variables and you can then change them inside a const function.
> I want to be able to change a classes implementation without altering
> its interface, so if a member function that was const, now becomes
> non-const, (eg if I add caching) why should clients care?
>
> Mark Jordan.
They shouldn't, which is why the language provides 'mutable' for exactly
this situation.
Best wishes,
Matthew Collett
In your original post you wrote that you couldn't remember a single case in
which const-correctness has helped you. Why do you expect to experience any
benefits from const-correctness if you don't enforce it?
Bo-Staffan
I agree with you that the compiler can't assume anything in this case. But
without enforcing const-correctness, it would severely limit the
opportunities to perform optimizations inherent to const objects.
Bo-Staffan
> The ripple through effect is poison in C because of its lack of function
> overloading (functions such as strtok() cannot be implemented in a const
> correct form in C)
Since everything else you say is true, it's a shame you chose strtok
as your example here. 'strtok' is a really, really bad example, since
it CAN (and is) implemented in a const correct form in C. The _only_
const-correct form of strtok is:
char *strtok( char *s1, const char *s2 );
A much better example is strchr, where the additional overload is
necessary for const-correctness.
char *strchr( char *, int );
const char *strchr( const char *, int );
(There are plenty of Other examples - 21.4p4 et. seq. lists a bunch of
them).
Regards,
Andy S.
For the benefit of IST5/-/21 members, I will now scream "stop it,
stop it - you're agreeing with me" :-)
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
But you're ignoring that const-correctness is a contractual
thing. You declare that a const mf doesn't change the underlying
object -- at least in the logical sense, if not the bitwise
sense. A const formal parameter or variable cannot be changed, by
definition -- unless you choose to cast away constness, of
course. Therefore, you can only use const mfs on const objects in
order to maintain the contract. If you want the option to modify
an object, then it must not be const, in which case you can use
const and non-const mfs on it.
If you don't want to deal with specifying those contracts, for
the compiler to automatically check for you, and instead rely on
the good will and behavior of yourself and other programmers,
then const-correctness will be a hindrance. Personally, I prefer
to have the compiler find my problems rather than wait until the
program misbehaves.
Rob
As a rule, comments that are not enforced by the compiler will rot over
time.
> My doubt about const correctness is that I never found
> compiler enforcement being really an help. I'm glad the
> compiler informs me I forgot a closed brace or that
> the "else" I typed is nonsense ... but when it tells
> me that I can't call that method because i've only a
> const reference as far as I can remember the error always
> was just in const-ness of the parameter or of the method
> declaration (and never that I was calling the wrong method
> or i was calling it on the wrong object).
> In other words I always found const-correctness only
> helping const-correctness.
I have quite an opposite viewpoint. I don't appreciate it when the compiler
nags me about minor obvious syntactic details such as those you mention.
They are so trivial, that even the compiler itself might add suggestions for
fixes to the error message. (I predict this is going to happen in the near
future; many compilers already advise about missing ";" at the end of a
class etc.)
Why would I be thankful or, as you say, "glad" that the compiler informs me
of the little fish? That's like saying, I'm glad that my stove can heat.
Duh! Even the darn *editor* could signal such problems by making those lines
red while editing!
What I'm glad about, is when design or programming errors are revealed as
type errors. (The stove has a mechanism that prevents it from overheating or
causing fire.) This is all what a type system is about.
Talking about 'const' in particular: it has been proven (and applied to
enable the entire field of functional programming) that immutable data
enables better reasoning for both humans and machines. Data that is not
modified after being initialized is much easier to track and reason about.
Even compilers often transform programs into "static single assignment" form
which does not really make all data constant, but enables reasoning about
the flow.
Your observation that const-correctness only helps const-correctness might
derive from the fact that the const qualifier forms cliques. Whenever you
find that the problem is actually something that is const shouldn't, you
move an entity away from the const-clique. Such a move is important and has
many implications; you shouldn't feel very easy about it. The bigger the
const clique is, the better grip you have on your program's state. And it is
of help that the compiler traces these cliques for you.
On a very practical vein, when examining code, it is of great help to see
exactly what data a function changes and what data it does not. (By the way,
there's no conceptual difference between a const method and a function
taking some const argument). This information is invaluable in figuring out
how the state of the program is affected by various function executions.
Also, const is useful for stack data because it simplifies code reading and
understanding. If you see:
const size_t sz = v.size();
you understand at a glance that sz is meant to be a snapshot of v's size for
the rest of the function. If const is not there, sz might change later - and
you need to trace the whole function to figure out what sz is meant to be.
IMHO, not appreciating const is a common error of a design beginner, in the
same way that not appreciating types/indentation/good names/decomposition
are common errors of a programming beginner.
Andrei
That is what the "mutable" modifier is for. Declare your cache variable
mutable and you can modify it in const member functions.
> So I don't use const member functions, not only are they a hassle to
> maintain, they are logically flawed!
> I don't suppose anyone agrees do they? :-)
Nope.
-Adam
> When
> was the last time you got a warning that you were trying to
> access private data?
<nitpicking>
I don't think anyone has ever seen a compiler warning when
trying to access private data -- in every single compiler
that I've worked with (ever since the days of Borland C++ 3),
that would produce a compiler error.
</nitpicking>
Carlos
--
I use it for most things. The exception is commands which need to return
some kind of status to say whether they worked. OOSC seems to recommend
storing the status in an instance variable and using another query to
get
it. Eg:
os.create_file( "filename" );
if (os.created_succeeded())
// ...
I dislike this because it adds more mutable state and I abhor mutable
state.
> I just do not happen to remember a single case in which
> compiler enforcement of const-correctness [...] actually helped
> me in discovering a true logical error.
I have known a few cases like that. They are rare because "const"
reflects
the way I think so there aren't many errors in code the compiler sees.
If I didn't have "const" I would often need to invent it. You will
often see discussion of this in Java groups (Java doesn't have "const").
Consider code like:
Point *p = circle.centre();
p->x += 1;
In Java there is no language-supported way to tell whether changing p
moves the circle it came from. Hence people either perform extra copies
to
ensure there are no side effects, or else they create read-only classes
by
hand.
That said, "const" adds enormous complication to the language, and makes
a
great deal of work for programmers. If I were designing a language I
don't
think I'd bother with it. As far as I know, C++ is the only language
which
does bother.
Much the same could be said of compile-time type-checking in general.
Most
errors which are caught by the static type-checker would be caught
during
testing anyway. I have used BCPL, an untyped language, and I think type
errors there only took around 10% of my debugging time.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."