On Friday, 21 July 2017 at 22:02:41 UTC, Jonathan M Davis wrote:
On Friday, July 21, 2017 08:37:51 Atila Neves via Digitalmars-d
wrote:
On Thursday, 20 July 2017 at 21:20:46 UTC, Jonathan M Davis
wrote:
> On Thursday, July 20, 2017 07:40:35 Dominikus Dittes Scherkl
>
> via Digitalmars-d wrote:
>> On Wednesday, 19 July 2017 at 22:35:43 UTC, Jonathan M Davis
>>
>> wrote:
>> > The issue isn't the object being destroyed. It's what it
>> > refers to via its member variables. For instance, what if
>> > an object were to remove itself from a shared list when
>> > it's destroyed (e.g. because it's an observer in the
>> > observer pattern). The object has a reference to the
>> > list, but it doesn't own it.
>>
>> So, even a thread-local object that has references to a
>> shared
>> list
>> has to handle those as shared, even in its non-shared
>> destructor.
>> I can't follow your argument.
>
> You can't just strip off shared. To do so defeats the
> purpose of shared. If you have something like
>
> struct S
> {
>
> shared List<Foo> _list;
>
> ~this()
> {
>
> ...
>
> }
>
> }
Wow. I've been doing too much C++ lately apparently, since I
used <>. :|
I noticed, but I wasn't going to say anything ;)
This is fine. What dmd does now is strip shared off of the
`this` pointer, not the member variables. There's only a
problem if the sharedness of the member variable(s) depends on
sharedness of the enclosing object.
What happens with something like
struct S
{
Foo* _foo;
~this() {...}
}
shared S s;
Inside the destructor, is what _foo points to still treated as
shared: shared(Foo)*?
No. This is what I meant by the sharedness depening on the
enclosing object. However, there's a workaround:
struct Foo { }
struct S {
Foo* _foo;
bool _isShared;
this(this T, U)(U foo) if(is(T == shared) && is(U ==
shared(Foo)*) || !is(T == shared) && is(U == Foo*)) {
static if(is(T == shared)) _isShared = true;
_foo = foo;
}
~this() {
import std.stdio: writeln;
_isShared ? writeln("shared dtor") : writeln("non-shared
dtor");
}
}
void main() {
auto f = Foo();
auto sf = shared Foo();
auto s = S(&f);
auto ss = shared S(&sf);
}
It's annoying to use that bool up memory-wise, but I assume it's
not a big deal for most applications.
In any case, that example wouldn't have worked anyway before my
change to dmd - even creating the S struct would've been a
compiler error.
Atila