logical const without casts!

Michel Fortin michel.fortin at michelf.com
Fri Sep 30 11:00:36 PDT 2011


On 2011-09-30 17:46:13 +0000, "Steven Schveighoffer" 
<schveiguy at yahoo.com> said:

> On Fri, 30 Sep 2011 13:38:31 -0400, Michel Fortin  
> <michel.fortin at michelf.com> wrote:
> 
>> On 2011-09-29 14:54:24 +0000, "Steven Schveighoffer"  
>> <schveiguy at yahoo.com> said:
>> 
>>> I just thought of an interesting way to make a logical const object   
>>> without casts.  It requires a little extra storage, but works without   
>>> changes to the current compiler (and requires no casts).
>>>  Here's the code, then I'll talk about the implications:
>>>  import std.stdio;
>>>  class D
>>> {
>>>      D getme() { return this;}
>>>      void foo() {writeln("mutable!");}
>>> }
>>>  class C
>>> {
>>>      D delegate() d;
>>>      this()
>>>      {
>>>        auto dinst = new D;
>>>        this.d = &dinst.getme;
>>>      }
>>>      void bar() const { d().foo();}
>>> }
>>>  void main()
>>> {
>>>      auto c = new C;
>>>      c.bar();
>>> }
>>>  outputs:
>>>  mutable!
>>>  So how does it work?  It works because delegates and especially the   
>>> delegate data is *not* affected by const.  So even when C is  
>>> temporarily  cast to const, the delegate is not affected (i.e. it's  
>>> context pointer is  not temporarily cast to const).
>>>  Doesn't this poke holes in const?  Of course it does, but no more  
>>> holes  than are present via another logical const scheme (i.e. using a  
>>> globally  stored AA to retrieve the data).
>> 
>> This is a hole in the transitive const, because the delegate contains a 
>>  pointer to mutable data. It also is a potential source of of low level 
>>  races since returning that type from a pure function could make it  
>> immutable, which can then make this mutable data accessible to multiple 
>>  threads with no synchronization or atomics to protect the data's  
>> integrity.
> 
> Simen Kjaeraas and Christophe brought up the same points.  I filed a 
> bug  on it:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=6741

Interesting proposal. You realize if we had a true 'mutable' storage 
class for class members it could obey the same rule as you propose in 
that bug report: it should be illegal to cast a mutable-containing 
object or struct to immutable implicitly. An explicit cast should be 
required.

Also, if we had shared delegates -- delegates which are guarantied to 
only manipulate shared data -- we could allow the class that contains a 
shared delegate to be implicitly converted to immutable.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list