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