Do we really need const?

Janice Caron caron800 at googlemail.com
Wed Sep 19 09:55:51 PDT 2007


On 9/17/07, Jarrett Billingsley <kb3ctd2 at yahoo.com> wrote:
> "Bill Baxter" <dnewsgroup at billbaxter.com> wrote in message
> news:fcl79k$18vu$1 at digitalmars.com...
>
> > It seems from the discussion here the past week, there is no real
> > multithreading benefit to be had from const/invariant.  'Pure' is where
> > it's at for that.  So maybe we're just better off without the complexities
> > of const.  I've certainly gotten used to the lack of const in Python, so
> > why not in a C++-ish language?
>
> I start to wonder how much of the "of COURSE we need const!" thinking comes
> from "if all you have is a hammer, everything starts looking like a nail."
> That is, I wonder how many people think we absolutely need const because
> they're so used to using it in C and C++.
>
> Never having learned a const-correct language (started with various BASICs,
> then on to very rudimentary C++, then D, and also a bit of Java and C#), I
> simply don't see the overwhelming need.  Sure, there are a very few cases
> where const could be useful in my code for efficiency's sake, but I've never
> felt like I was missing any expressive power.  Furthermore, I have been
> bitten exactly once by something that theoretically could have been
> prevented by const.  It took me two minutes in the debugger to track down
> the problem.  I'd say that those two minutes were a much better tradeoff
> than the god-knows-how-long it'd take to write const and non-const overloads
> of who-knows-how-many functions.

Let me share some real world experience about using const versus not
using const.

Today, I found myself writing a small standalone project in D, for my
own personal use. I wrote a function that took a ubtye[] as it's
parameter. It occured to me that the function didn't actually modify
the array, so (since I have D2.0) I could have declared the parameter
const. I considered it, and then I thought: "Nah... let's not bother.
Too much effort".

BUT...

When working on a big project, it's a different story. A couple of
years back, I was team leader in a C++ project with half a dozen other
developers. It was a multithreaded application. So I wrote this bunch
of classes which had to be called in a certain way or it wouldn't
compile - because data had to be shared between server instances and
so forth. Well, a couple of the developers figured out the right thing
to do all by themselves, and that was great. Of the others, about
three tried the "obvious", discovered that it wouldn't compile because
of const-correctness, and came to me asking why not. I explained that
there was good reason for the constness, that it was thread-safety
issue, and then I told them the correct, "authorised" way of doing
things, and then they went off and did the right thing. So in this
case, const forced everyone to get it right. Well - almost everyone.
(There's always /one/!) One team member tried the "obvious",
discovered that it wouldn't compile, and then, instead of asking me
why not, figured out a workaround to make it compile using pointers.
(If C++ had had intransitive const, the compiler would have prevented
this, but it doesn't so he got away with it). Then ... weeks later ...
we found that the server randomly fell over after several hours of
problem-free up-time. The symptoms were random memory corruption. It
took us about a month to find and fix the problem! Care to guess what
the problem turned out to be? Yes, it was that errant team member's
workaround for const-correctness that ended up causing multiple
threads to (rarely) become thread-unsafe. (Moral: If your code won't
compile when you try to call a co-worker's function, don't hack up a
workaround - instead, ask them if you're calling it right!)

So what I conclude from this is:

(1) For a small project, you can ignore const. Just because the
language has it, doesn't mean you have to use it.

(2) For a large project, it's essential. And moreover, it needs to be
transitive by default.

I don't have a problem with const being transitive by default. I think
it's a good idea. I do, however, have a problem with there being *no
way to specify* mutable pointer to const pointer to mutable data.
We've listed enough use cases to know that sometimes that's exactly
what you need. It shouldn't be the default, but it should be
/possible/.

But ... on the other hand ... we /can/ cast away const, and even
though it's "undefined", there is some indication that you can get
away with it if you know what you're doing (in terms of
thread-safety), so maybe it's not as big a problem as some of us
imagine.

Anyway, there's my story and my conclusions. Hope it helps. If not,
hope it kept you amused. :-)



More information about the Digitalmars-d mailing list