Shared

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu May 16 10:50:48 UTC 2019


On Thursday, May 16, 2019 4:17:15 AM MDT Dominikus Dittes Scherkl via 
Digitalmars-d wrote:
> On Wednesday, 15 May 2019 at 09:33:19 UTC, Jonathan M Davis wrote:
> > You can't forbid references to the same data. All that would be
> > required would be something like
> >
> > shared foo = new shared(Foo)(42);
> > auto bar = foo;
>
> Meep. This is either a compile error outside locked block (cannot
> read shared) or bar would be scope (it's lifetime will end after
> lock block is left).

If you can't pass shared class references or pointers around like this, then
it wouldn't even be possible to call shared functions on shared objects,
because that's what happens when you call a function. And that really would
make shared ridiculously hard to use. It would make it impossible to
encapsulate thread synchronization primitives and force the programmer to
handle it directly. Things like a shared class or struct that handled its
own locking would be impossible, because you couldn't even call any of its
methods. Code like

shared foo = new shared(Foo)(42);
auto bar = foo;

needs to work as long as the type being passed around is a pointer or class
reference, or shared simply won't be useable.

> > and you have two references to the same object without doing
> > anything unsafe. You could also have stuff like
> >
> > shared baz = foo.getBaz();
>
> This will be forced to a copy of the returned value, not a
> reference.

No matter what the return type is, a line like that would either copy or
move the return value (which one would depend on the implementation of
getBaz and what exactly it was returning), but for a pointer or class
reference, that just means that you have a pointer or class reference
referring to the same thing as something that was in getBaz. So, copying is
the normal semantics. And if you're trying to claim that it should be a deep
copy, D doesn't even have that capability for classes - not without there
being user-defind functions which do it, and the compiler won't know that
that's what they do and couldn't use them automatically. So, that wouldn't
work even if it were desirable - and it wouldn't be, because you really
don't want to be deep copying classe normally. And you _really_ don't want
to be doing it if shared is involved; that would require locking in a way
that copying a simple pointer or reference shouldn't (at least not if we
want to be able to actually do stuff like call shared member functions).

Also, just in general, trying to prevent other references to the same data
with shared actually makes no sense. If you don't have multiple references
to the same data, then there's no point in it being shared in the first
place, because you won't have multiple threads accessing the data. Even with
TDPL synchronized classes, which prevent references to the member variables
from escaping, you still have multiple references to the class itself - and
the class itself is shared. Multiple references to the same data is a key
part of data being shared. At best, you can avoid it by having only a single
reference to some shared data with multiple references to a shared object
which has the single reference to the other shared data (i.e. what you get
with TDPL synchronized classes). And if that's what you're doing, then you
might as well just have TDPL synchronized classes rather than trying to do
something more free-from.

- Jonathan M Davis





More information about the Digitalmars-d mailing list