How to break const

deadalnix deadalnix at gmail.com
Mon Jun 18 07:33:25 PDT 2012


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 ».


More information about the Digitalmars-d mailing list