Is it possible to modify shared struct array in a function.
Jonathan M Davis
newsgroup.d at jmdavisprog.com
Sat Feb 9 02:19:27 UTC 2019
On Friday, February 8, 2019 4:27:44 AM MST Eduard Staniloiu via Digitalmars-
d-learn wrote:
> On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote:
> > On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote:
> >> On Friday, 8 February 2019 at 04:30:23 UTC, Arun
> >>
> >> Chandrasekaran wrote:
> >>> On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote:
> >>>> [...]
> >>>
> >>> Works fine for me with DMD64 D Compiler v2.083.1.
> >>> https://run.dlang.io/is/RRM8GU
> >>
> >> My example code was wrong. Below is the right one.
> >>
> >> struct Company
> >> {
> >>
> >> string name;
> >> string location;
> >>
> >> }
> >>
> >> struct Racks
> >> {
> >>
> >> int number;
> >> int location;
> >>
> >> }
> >>
> >> struct Metadata
> >> {
> >>
> >> string name;
> >> Company[] companies;
> >> Racks[] racks;
> >>
> >> }
> >>
> >> struct Item
> >> {
> >>
> >> Metadata[] met;
> >> int count;
> >>
> >> }
> >>
> >> shared (Item) item;
> >>
> >> void main()
> >> {
> >>
> >> updateMetadata();
> >>
> >> }
> >>
> >> void updateMetadata()
> >> {
> >>
> >> Company company;
> >> company.name = "Hello";
> >> company.location = "Bangalore";
> >> item.met.companies ~= company;
> >> import std.stdio: writeln;
> >> writeln(item);
> >>
> >> }
> >>
> >> https://run.dlang.io/is/iem0PY
> >
> > You have to cast away shared:
> >
> > auto loc_item = cast(Item) item;
> > loc_item.met ~= m;
> > item = cast(shared) loc_item;
> >
> > Just to be clear, this is not threadsafe and require a mutex if
> > you do this other than as init in main.
>
> You do not need to cast away shared. You had a couple of issues
> with your `updateMetadata()` function.
>
> First of, `met` is an array, so you need to index it: your code
> `item.met.companies ~= company` becomes `item.met[0].companies ~=
> company`. This will compile, but throw a range error because you
> don't have any `Metadata` object in your `met` array.
>
> I have typed below the revised form of your function
>
> ```
> void updateMetadata()
> {
> // create a Company instance. This must be shared
> shared Company company;
> company.name = "Hello";
> company.location = "Bangalore";
>
> // create a shared Metadata instance
> shared Metadata m;
> m.name = "m";
>
> // append m to the array of meta
> item.met ~= m;
> // append the company to the array of companies, for a given
> meta
> item.met[0].companies ~= company;
>
> import std.stdio: writeln;
> writeln(item);
> }
> ```
>
> The working version is at https://run.dlang.io/is/RvRKrU
>
> Cheers,
> Edi
Honestly, the fact that that code compiles is a bug. You're not supposed to
be able to modify shared objects in a manner which isn't guaranteed to be
atomic, because it's not thread-safe. The compiler catches it in a number of
places, but there are many where it currently doesn't.
But regardless of whether the compiler allows such mutation, a mutex (or
similar protection mechanism) needs to be used in order to make the code
thread-safe.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list