An Issue I Wish To Raise Awareness On

Atila Neves via Digitalmars-d digitalmars-d at puremagic.com
Mon Jul 24 07:30:01 PDT 2017


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


More information about the Digitalmars-d mailing list