Yes. The shared-ness, const-ness or immutable-ness of the _this_ parameter is defined by marking the method itself shared, const or immutable respectively. But marking the method shared or immutable makes that method callable _ONLY_ for shared or immutable objects of that class or struct respectively. In order to make that struct usable from both shared and non-shared contexts, you need to have 2 overloads of that method: shared and non-shared.
On Tue, Oct 25, 2011 at 4:22 PM, Timon Gehr <[email protected]> wrote: > On 10/25/2011 08:36 AM, Andrew Wiley wrote: >> >> On Tue, Oct 25, 2011 at 1:26 AM, Benjamin Thaut <[email protected] >> <mailto:[email protected]>> wrote: >> >> Am 25.10.2011 08:06, schrieb Andrew Wiley: >> >> Geez, I try to write some multithreaded code and I just keep >> hitting these: >> -------- >> module test3; >> >> struct SomeData { >> int i; >> int iPlus2() { >> return i + 2; >> } >> } >> >> synchronized class Bob { >> private: >> SomeData _dat; >> public: >> this() { >> _dat.i = 3; >> } >> @property >> int i() { >> return _dat.iPlus2(); // test3.d(22): Error: function >> test3.SomeData.iPlus2 () is not callable using argument types () >> shared >> } >> } >> -------- >> >> This seems like it should be legal because SomeData is a value >> type. >> Accessing _dat.i directly is legal, and _dat can't possibly be >> shared. >> If I'm understanding things correctly, transitive shared >> shouldn't apply >> to value types like this, so the type of "this" when calling iPlus2 >> should just be SomeData. >> >> >> It can't be garantueed that a pointer to _dat is not given away at >> some point in the program. For example you could have a clas Foo >> that inherits from Bob and has a getter for _dat. Then it wouldn't >> be correct anymore to sasume _dat is unshared. Because of that it >> has been decided that trying to figure out if _dat has to be shared >> or not will not happen, thus its just shared always. I've already >> reported this some time ago and essentially it makes synchronized >> classes useless for me. I usually just write a normal class and but >> the synchronized blocks in myself. Also I use __gshared ;-) >> >> >> Alright, but why can I access _dat.i without synchronization? > > _dat.i is shared by transitivity. You can access shared variables without > synchronization (according to TDPL, memory barriers are inserted > automatically, but I don't know if DMD implements this). SomeData.iPlus2's > implicit 'this' parameter is not shared. >
