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

Reply via email to