Transitive const sucks

Janice Caron caron800 at googlemail.com
Tue Sep 11 09:53:19 PDT 2007


On 9/11/07, Steven Schveighoffer <schveiguy at yahoo.com> wrote:
> "Janice Caron" wrote
> > What all of these use-cases have in common is the fact that the state is
> > private
> >
> > Suppose that all class and struct members which were declared private,
> > were always mutable,
> > even if the class instance is const.
>
> I sort of agree with you,

I believe I can make the case for my argument stronger. In general,
when I expose a class's interface, the understood contract is:

 class C
 {
     public:
         /* stuff I want you to know about */

     private:
         /* None of your gorram business. It's PRIVATE.
            You shouldn't care know or care what's in here */
}

To a caller of the code, it should not matter what member functions of
C do to its private members, so long as the public interface does what
you expect.

Here's another use case. Suppose I start off with a simple class like:

 class C
 {
     void f() { /* do something */ }
 }

 const C c;
 c.f();

But later, as I'm debugging the code, I realise it's not doing quite
what I want it to do, and I need to put some diagnostic code in to
help me with debugging. So I change it to:

 class C
 {
     void f() { debug ++count; /* do something */ }
     debug private int count;
 }

 const C c;
 c.f();

Whoops! Now it won't compile in debug mode (but it will still compile
in release mode). Again, it's because /private/ state is conflicting
with the constness.



> but what about instances where you want derived
> classes to be able to access the cache?

I can't think of a use-case for that.

Would it not suffice for the base-class to expose protected functions
to provide read-only access to the cache?



> I think having a keyword for mutable is necessary

I believe this thread has shown that there is a need for the
/functionality/ that the keyword provides, but I'm not completely
convinced that we need the keyword itself. If we allow private data to
be implicitly mutable then we don't need the keyword.


> but what may make sense
> is to enforce that only non-public members are allowed to be mutable.

My idea would make that enforcement unnecessary


> What is the argument against mutable again?

In C++, you can do this:

 class C
 {
 public:
     mutable int x;
     C() { x = 0; }
     void f() const { x = 5; }
 }

 main()
 {
     const C c;
     printf("%d\n", c.x); /* prints 0; */
     c.f();
     printf("%d\n", c.x); /* prints 5; */
 }

This is clearly nonsense.

That would be disallowed in my scheme. (...at least, if main() was in
a different file from the definition of C).



More information about the Digitalmars-d mailing list