logical const without casts!
Steven Schveighoffer
schveiguy at yahoo.com
Fri Sep 30 11:07:54 PDT 2011
On Fri, 30 Sep 2011 14:00:36 -0400, Michel Fortin
<michel.fortin at michelf.com> wrote:
> 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.
Yes, but the benefit of the proposal is -- it already works in the current
compiler :) You have a monstrous hill to climb to convince Walter to
*add* mutable storage class, but we don't even have to ask for this one,
it works today.
> 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.
I'd like to avoid the complication of having any attributes that apply to
the context pointer. I like how delegates just fit in anywhere, no matter
what the context pointer type is (or its constancy).
-Steve
More information about the Digitalmars-d
mailing list