const - Best practices

Jonathan M Davis jmdavisProg at gmx.com
Sun Jan 2 14:43:29 PST 2011


On Sunday 02 January 2011 10:41:16 Peter Alexander wrote:
> On 31/12/10 6:33 PM, Peter Alexander wrote:
> > Ok, so while I'm still not 100% satisfied with the lack of logical const
> > in D, I'm willing to see how far I can get without bitwise const without
> > going crazy, and I just want to clarify some things.
> > 
> > Andrei has commented a couple of times on the fact that D's const has
> > more guarantees than C++'s const, and as a result you should use it a
> > lot less often than you do in C++.
> > 
> > Questions:
> > 
> > 1. What exactly does this mean? What are the situations where you should
> > use const in C++, but not in D?
> > 
> > 2. When designing base classes and interfaces, when should you mark a
> > member function as const? In C++ you would do so for any accessor, as
> > they would be logically const. In D, you can't assume that an accessor
> > is bitwise const (due to lazy initialisation and caching), so when do
> > you make it const in the base class, and when do you leave it mutable?
> > 
> > 3. When should you take const references in template functions
> > (essentially same subquestions as above).
> > 
> > Final note: my intention here is not to start another logical const vs.
> > bitwise const war. I just want to know how the differences in const from
> > C++ affect library design, and what the best practices for
> > const-correctness are in D.
> > 
> > Thanks in advance.
> 
> Sorry for the bump, but there's at least three people here that would
> like an answer to this. Surely someone knows how to use const in D? :-)
> 
> Additional question: why are none of Object's methods const, e.g.
> toString and toHash?

http://d.puremagic.com/issues/show_bug.cgi?id=1824

For the const/immutable situation to be totally useable, several dmd bugs must 
be fixed. Some of the major ones are 1824 (Object is not const-correct), 3659 
(opEquals() and const needs to be sorted out), 4867 (postblit doesn't work with 
const objects), and 3748 (inout is broken). The auto ref issue which came up 
recently when discussing the fact that const ref doesn't work with temporories 
needs to be resolved as well.

There are a number of critical issues with const and immutable as things stand. 
The result is that that they can quickly become rather problematic to use 
correctly, if not outright impossible. There are definitely cases where const and 
immutable can and should be used, but you really have to want to use them at 
this point to be able to manage it, because they have a lot of problems. And 
until those problems are fixed, there's no way that we can know what the "best 
practices" of const in D will really be. To really understand that, we need to 
write code which uses const and immutable heavily and really see how it all 
works out. We can speculate on what we think will work well and point out areas 
where it's clear that there will be problems or which will pretty much need to 
use const in some manner (like opEquals()), but not enough people have been 
using const for there to be much experience with it, and those who have tried 
have consistently run into serious bugs which prevented them from using it like 
they'd like to.

Another big thing is that Phobos as a whole is not const-correct. I don't 
believe that much attempt has been made to ensure that many of Phobos' functions 
work properly when const and immutable are used. The lack of tail-const for 
arbitrary ranges is one of the big open issues which has yet to be resolved. As 
I understdand it, there are some things work for arrays which will never work 
for other ranges. And some things have worked in the past because of compiler 
bugs. Such bugs have hidden issues (including issues relating to const) and made 
it look like const worked where it doesn't. Until Phobos is properly const-
correct, there are a lot of cases where you're not going to be able to use const 
(this is also true for purity, though I believe that the situation is quite a 
bit worse for purity).

I expect that there is going to have to be a definite focus on fixing bugs related 
to const and immutable in both the compiler and in Phobos before const and 
immutable will really be generally useable. It's on the TODO list, though it's 
not clear whether that or dynamic libraries is next after the 64-bit port 
(regardless, the 64-bit port is taking longer than expected so, it's going to be 
longer before the rest of the stuff in line gets focused on and fixed).

Personally, I think that const should be used as much as it can be reasonably 
used. But it does generally preclude any kind of caching of values and the like 
that you could do with logical const (though you could do things like have a 
mutable version of a getter on top of a non-mutable one and have _it_ cache the 
value, so that if either it or the const version is called later and the value 
doesn't need to be recalculated, the const one can use the cached value and 
still gain some efficiency from caching). So, if you're expecting to have to cache 
values and the like, then don't use const.

But honestly, in my experience in C++, I have almost never used mutable. And 
when I have, it's generally been for mutexes and the like (which won't be 
necessary in the same way in D). Doing things like caching calculations is 
extremely rare. So, the lack of logical const really wouldn't affect much from 
what I've seen. The transivity of const is what really affects things IMHO 
(things like returning a list of mutable objects from a const getter where that 
list is a member variable of the object aren't going to work in D, but they work 
just fine in C++ since the container itself isn't copied). I'm sure that there is 
code out there which does high-cost calculations on a regular basis and pretty 
much needs to be able to cache the results to be properly efficient, but that is 
not the norm. So, while some people are going to acutely feel the lack of 
logical const, a _lot_ of people are going to be able to use const in D very 
much like they do in C++ without having any issues with the lack of logical 
const. _Transivity_ may very well make it impossible to use const like they 
would have in C++, but the lack of logical const really isn't that big a deal in 
_most_ cases.

- Jonathan M Davis


More information about the Digitalmars-d mailing list