How to break const

Christophe Travert travert at phare.normalesup.org
Mon Jun 18 08:14:11 PDT 2012


Matthias Walter , dans le message (digitalmars.D:170036), 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.

But here, the frame pointer of the delegate is part of the const 
structure. By transitivity, the frame pointer should be const, and 
therefore, calling the delegate (which modifies the frame pointer) 
should not be legal.

To be callable from a const method (oops), the member delegate 
(increment) should be of type "void delegate() const". This type exists, 
but is not easy to get[1]. Because constness of frame pointers is not 
implemented as it should be[2], there is a hole in the const system.

[1] AFAIK, it can only be got by making an explicit delegate like 
&struct.const_method
[2] Just like pure and no_throw attributes are complicated to work with 
delegates, the const attribute would be a mess to use at the moment.

-- 
Christophe


More information about the Digitalmars-d mailing list