How to break const

Steven Schveighoffer schveiguy at yahoo.com
Mon Jun 25 07:08:35 PDT 2012


On Mon, 18 Jun 2012 01:36:26 -0400, Mehrdad <wfunction at hotmail.com> 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);
> }

This is quite a long thread, and I didn't read everything, but here is my  
take on this:

1. The issue is that the context pointer of the delegate, even though it  
is stored as part of the struct data, is not affected by coloring the  
containing struct as 'const'.

2. The issue is simply with delegate implicit casting, which the compiler  
does just about nothing with today.

Consider the following struct:

struct S
{
    int x;
    void foo() {++x;}
    void fooconst() const {}
}

Now, consider the following function:

void callit(void delegate() dg) { dg(); }

One of the *really* cool benefits of delegates is that you can pass both  
foo and fooconst to callit -- callit doesn't have to care what attributes  
are applied to the delegate's context pointer, it simply calls them.

However, consider if we *want* to make sure dg doesn't modify its context  
pointer, how can we write dg's type?  You could do this (if it worked):

void callit(void delegate() const dg) { dg(); }

What should this mean?  In my interpretation, it should mean that only a  
delegate that uses a const context pointer should be able to be bound to  
dg.  So &foo should *not* be able to be passed to callit.

If we can implement something like this, I think the problem would be  
solved.  What would happen to your original code?  oops would not compile,  
because you could not automatically convert a delegate to a const delegate  
(unless it was marked as const).  And I think it would be possible to keep  
the nifty feature of not caring what the context parameter is marked as.

-Steve


More information about the Digitalmars-d mailing list