const?? When and why? This is ugly!

Burton Radons burton.radons at gmail.com
Fri Mar 6 17:37:02 PST 2009


Andrei Alexandrescu Wrote:

> Burton Radons wrote:
> > Andrei Alexandrescu Wrote:
> > 
> >> This is a known problem for hich we will provide a solution.
> > 
> > If you have something which works everywhere please tell us because
> > we've been trying to find one for a long time, but as far as I know
> > there is no solution. The best I've ever gotten to is:
> > 
> > // "A" means that the constness of the return type depends upon the
> > constness of the argument. There are dozens of ways to specify the
> > same thing. const (A) mstring match (const (A) mstring text, RE
> > expression);
> > 
> > But setting aside whether that helps or hinders self-documentation,
> > that's far from the only place at which you put mutable data through
> > a const section that you need to modify later. What if the function
> > were instead:
> > 
> > struct REMatch { string match; /// The matched string. size_t offset;
> > /// Offset within the string where the match occurs. string []
> > groups; /// Matched groups.
> > 
> > this (string text); }
> > 
> > What am I going to do about this now without using templates? If you
> > define a special syntax to make this work, then I can give you
> > something even further which won't.
> 
> The problem is you set up artificially constrained rules, i.e. "without 
> using templates". You can't use the same struct to store mutable types 
> and non-mutable types mixed with always-mutable types, and for good 
> reasons. No type system will allow 100% of the correct programs to run. 
> Why the fuss. Use a gorram template and call it a day.

Ah, so you don't have a solution.

What you'll have instead are programs which are developed one way but then come to an impasse where they need to cast off const but can't. So after some cursing, the programmer starts wasting his time modifying all of his code to be templated, because avoiding casting off const has exactly the same viral progression as adding in const (I did it in C++ the last time we thought const might be able to make code better-optimised).

This goes fine, until he comes up to a library which hasn't gone through the same process, so it has a normal interface. Or he comes up to an interface itself, which will not normally be templatable. He doesn't have the code, so he can't change the library. What does he do then?

There are four options I can see. One, he could make a copy of the supposedly const data that's been trapped by the library, which won't always work. Two, he could take the pointer and length from the slice and figure out where in his mutable data the slice exists at, which might be impossible depending upon pointer arithmetic restrictions. Three, he could reimplement the library functionality himself, which may be impossible. Four, he could move on to a language which doesn't make his job hard just so that it can sometimes add numbers faster.

This is actually reminding me of C++ the more I think about it. C++'s bad features are so bad because they're far-reaching but they couldn't be consistently applied. So if you read the specification, you'll find twenty or so caveats that try to make the feature work, when the proper thing to have done was to realise that a feature which doesn't naturally fit in a language shouldn't be in that language. Yet here we have a feature that's not just C++, but it's C++^2.

Multiple keywords. The threat that abuse will eventually lead to code being compiled incorrectly, coupled with forcing abuse on common code (I stress that any data which is marked as invariant at any point but is not actually invariant will cause optimisation issues if it's given any weight whatsoever). At least three different ways to define a const. "const int *foo ()" and "int *foo () const" equivalency. A syntax which makes declarations hard to read. And coming, you say, is enforced const-correctness, just to make things extra awful.



More information about the Digitalmars-d mailing list