What functions can be called on a shared struct that's implicitly castable to immutable?

Maxim Fomin maxim at maxim-fomin.ru
Mon Nov 4 02:28:42 PST 2013


On Sunday, 3 November 2013 at 21:55:22 UTC, Simen Kjærås wrote:
> Consider:
>
> module foo;
>
> struct S {
>     immutable(int)[] arr;
>     void fuzz() const pure {
>     }
> }
>
> void bar(S s) {
>     s.fuzz();
> }
>
> void main() {
>     shared S s;
>     bar(s);   // a
>     s.fuzz(); // b
> }
>
>
> In this case, the line marked 'a' works perfectly - it compiles 
> and does what I'd expect it to.
>
> However,the line marked 'b' does not compile - " non-shared 
> const method foo.S.fuzz is not callable using a shared mutable 
> object ".
>
> The reason for this is that fuzz takes the 'this' pointer by 
> reference, and so risks that another thread corrupt the 
> internal state while it's working.
>
> Seeing as line 'a' works, it seems safe for line 'b' to make a 
> copy behind the scenes

Why should method call invole copy? This breaks lots of 
assumptions and it would be a pretty weird corner case.

> (structs in D are defined to have cheap copying, I seem to 
> recall)

Why? There is no restrictions on postblit, so copying may be 
cheap as well as arbitrary costly.

> and call fuzz on that copy - the type system claims that the 
> call to fuzz cannot possibly change the state of the struct on 
> which it is called.

Your problem may be solved pretty simple:

pure fuzz(S s)
{
	
}

and be happy with s.fuzz() operating and copy if you want so. 
Does it address your problem?

> With the state of 'shared' as it is, I'm unsure if this is a 
> change that should be done - it seems perhaps better to wait 
> for a true overhaul of the feature.

What shared means in D is not trivial question, I agree.


More information about the Digitalmars-d mailing list