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