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.