How to break const

Timon Gehr timon.gehr at gmx.ch
Mon Jun 18 08:17:37 PDT 2012


On 06/18/2012 04:33 PM, deadalnix wrote:
> Le 18/06/2012 15:03, Timon Gehr a écrit :
>> On 06/18/2012 02:45 PM, deadalnix wrote:
>>> Le 18/06/2012 07:59, Matthias Walter a écrit :
>>>> On 06/18/2012 07:36 AM, Mehrdad wrote:
>>>>> Is it just me, or did I subvert the type system here?
>>>>>
>>>>>
>>>>> import std.stdio;
>>>>>
>>>>> struct Const
>>>>> {
>>>>> this(void delegate() increment)
>>>>> { this.increment = increment; }
>>>>> int a;
>>>>> void delegate() increment;
>>>>> void oops() const { this.increment(); }
>>>>> }
>>>>>
>>>>> void main()
>>>>> {
>>>>> Const c;
>>>>> c = Const({ c.a++; });
>>>>> writeln(c.a);
>>>>> c.oops();
>>>>> writeln(c.a);
>>>>> }
>>>>>
>>>>
>>>> I don't think so. When calling oops you have two references to the
>>>> object c:
>>>>
>>>> - The this-pointer of the object itself which is not allowed to change
>>>> the object in the const-call.
>>>> - The reference from within main which is allowed to change it and can
>>>> be reached via the frame pointer of the delegate.
>>>>
>>>> I see this as perfectly valid code. Of course, opinions may differ
>>>> here.
>>>>
>>>> Matthias
>>>
>>> The hidden parameter of the delegate is stored in c. This hidden
>>> parameter must be qualified with const when c is made const, for
>>> transitivity. However, it isn't.
>>>
>>> In short :
>>> - c is made const
>>> - the frame pointer is stored in c
>>> - the frame pointer must be made const for transitivity.
>>>
>>> => The type system is broken. You'll find many examples of this behavior
>>> with delegates.
>>
>> The type system is not broken. You cannot modify an immutable object
>> using this behaviour. Delegates are type checked once and for all when
>> they are declared. Transitive const does not necessarily need to
>> apply to their context pointers. I think it is useful to reason about
>> delegates at a higher abstraction level than function pointer and
>> context pointer.
>>
>
> You cannot use this to modify immutable data, granted.
>
> But you can use that to break transitivity (ie, make immutable data
> refers mutable datas). It have many hidden traps. For instance, data
> that isn't shared or immutable can be shared anyway between thread throw
> delegates.
>
> Not being able to ensure transitivity with delegate break all benefit of
> transitivity.
>
> However, delegate is a special beast, because it cannot be safely «
> constified », but can be safely « unconstified ».


The issue is that immutable objects can contain impure delegates as 
fields. This should probably be banned.




More information about the Digitalmars-d mailing list