const(FAQ)

Kevin Bealer kevinbealer at gmail.com
Sat Mar 29 12:28:18 PDT 2008


guslay Wrote:

> Kevin Bealer Wrote:
> 
> > guslay Wrote:
> > 
> > 
> > I would suggest that in many cases, D interfaces should avoid const since you can't know if lazy evaluation and similar are needed.  Using const here is a case of overspecifying, like an interface that takes a reference to a "StudentCheckingAccount" object but only uses methods from the parent interface "CheckingAccount" or grandparent "Account" object (assume an inheritance hierarchy following the names.)  Demanding that a concrete class be const is a larger burden than in C++ since there is no workaround.
> 
> That's why I feel that this is the biggest threat to the adaption of a const-correctness policy in large D programs.
> 
> You are basically saying don't use const unless you know all the implementation details about a class, and don't put const in Interface/abstract class, just in final concrete class.

Yes and no.  You can make the interface methods const but not do lazy evaluation later, or you can make them non-const and leave the door open.  But you have to decide.  You can change the decision later but its like any const-correctness-scheme change, it can potentially bubble up the code dependency tree.

A lot of C++ programmers seem to follow a concept that everything should be const all the time unless there is a reason not to.  In the D const world, the cost of const is higher so you really have to ask the cost/benefit question -- does this buy me anything -- when applying const.  For interfaces and base classes, this answer will be no more often than for concrete classes.

> As you point, casting away constness is not an option. You need a way out, otherwise const will just be used for trivial things.

In C++, const is about observable values via a human-understood subset of the public interface (e.g. if a method changes a string's capacity() but not its size or data, is it still logically const?).  In some cases, it seems like const only applies to an object's position in a sort order.  It's like advisory locking in unix.

In D it is about reentrant safety and bits.  The C++ version is more useful as a guideline for communication between programmers, but the D version is more useful as a guarantee about code behavior.

> > > - Could you elaborate more on what mutable members would 
> > > break/prevent, if used reasonably?
> > 
> > The idea is that "const" in D means that the compiler can guarantee that no side effects happen.  First, if you call a method several times, can the compiler eliminate the subsequent calls?
> > 
> > for(int i = 0; i != v.size(); i++)
> >   cout << v[i];
> > 
> > The compiler has to call v.size() for every iteration in C++.  In this case, if both v.operator[](int) and v.size() are inlined and simple then the compiler (might) be able to check constness via data flow analysis. But if not, the compiler can't cache .size() because in C++ the const might be "logical".
> 
> Logical const is still const, as far has there is no visible (public) side effect on the object. The implementation is still bound to that contract. The result of .size() may still be cached.

Assuming the person writing the code made sure of this... But once you have mutable members, the compiler cannot rely on the value of size() changing or not, it becomes a human decision. Is the value of vector.capacity() allowed to change?  From the point of view of the "value" of the vector, yes.  From a compiler/optimization point of view, no.

To some extent, this could actually be fixed in C++ simply by the standards committee saying that its okay for a compiler to rely on repeatability of method return values and to omit duplicate calls to methods.

> So, there a way around it. You can outsource the mutable part to a static/global.
> 
> This is a side effect. Why not allow a mutable private members, and keep those implementation details encapsulated within the class. This code is not more guaranteed to be "reentrant" that mutable one.
> 
> With const, you promise that the object that will exhibit to the outside world a const behavior. However, you cannot say that a const-call has no side effect at all. 
> 
> In other words, const does not mean pure, with or without mutable members.

You're right - the definition of "pure" in this sense is much stronger than "const", so I overstepped here.  In this case "const" is not "pure" but is kind of like "pure" relative to the object in question, so some of the optimization might not be as possible unless all behaviors of the method are "read" rather than "write", not just those affecting internal state of this object.

But the "pure" keyword is reserved, so maybe we'll see that as well.

Kevin




More information about the Digitalmars-d mailing list