Why D const is annoying

Jonathan M Davis jmdavisProg at gmx.com
Wed May 2 01:23:25 PDT 2012


On Wednesday, May 02, 2012 01:12:15 Mehrdad wrote:
> > > Wouldn't "physical" const-ness be an implementation detail of the
> > > object, and therefore, impossible to determine by the user of the
> > > object?
> > 
> > No, it's not an implementation detail. When you mark an object as being
> > physically const, then you're guaranteeing that you will not alter it
> > through that reference or pointer.
> 
> I think you misunderstood my question.
> 
> Yes, __IF__ you mark an object as physically const, then the world is
> beautiful...
> 
> My question is, __WHEN__ can you ever do that, except in the most trivial
> situations?
> As soon as you try to add an extra layer of indirection (be it a proxy,
> implementing a method in an interface, overriding a base class method,
> etc.), there is NO WAY for the caller to know what obj.foo() does on obj.
> How can it possibly know whether obj will stay physically const?h

Because foo must be const, or if can't be called on a const object. And if 
it's const, then it can't call any non-const functions or mutate any of its 
member variables. If you have

interface I
{
    int foo() const;
}

class C : I
{
    int foo() const
    {...}
}

C's foo _must_ be const, or it's not implementing I's foo, and it won't 
compile. And if C's foo is const, then it can't call a non-const function or 
mutate any of its member variables. If it were pure on top of that, then it 
couldn't mutate any global or class variables either. The same goes for any 
derived class which overrides foo. const is part of foo's signature, and no 
derived class can escape that. So, _every_ class which implements I, and 
_every_ class derived from C will have a const foo which will be unable to 
mutate the state of that object.

If instead you did

class D
{
    int bar() const
    {
        return e.bar();
    }

    E e;
}

then E's bar would have to be const, or it wouldn't be callable from D's bar, 
since the e member variable is const inside of D's bar, since D's bar is 
const, and you can't call a non-const function on a const variable.

An extra layer of indirection doesn't escape const at all, because that layer 
of indirection must use const or it won't be usable by the outer layer. So, 
the type system is able to guarantee that when you call a const function, the 
object it's being called on - as well as any object that it contains directly 
or indirectly - will not be mutated.

- Jonathan M Davis


More information about the Digitalmars-d mailing list