Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
February 08, 2019 Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
I have a situation, where i want to modify a shared variable in a function. Something like below 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; } Compiler throws me error in last line for appending as below. "cannot append type Metadata to type shared(Metadata[])". Please let me know if there is a way to acheive this. Thanks, Sudhi |
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sudhi | On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: > I have a situation, where i want to modify a shared variable in a function. Something like below > > 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; > } > > Compiler throws me error in last line for appending as below. > > "cannot append type Metadata to type shared(Metadata[])". > > Please let me know if there is a way to acheive this. > > Thanks, > Sudhi Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU |
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | 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: >> I have a situation, where i want to modify a shared variable in a function. Something like below >> >> 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; >> } >> >> Compiler throws me error in last line for appending as below. >> >> "cannot append type Metadata to type shared(Metadata[])". >> >> Please let me know if there is a way to acheive this. >> >> Thanks, >> Sudhi > > 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 |
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sudhi | 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:
>> [...]
>
>
> 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
`shared struct Metadata` should make it work.
Turtles (shared) all the way down.
|
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sudhi | 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.
|
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jerry | 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 |
February 08, 2019 Re: Is it possible to modify shared struct array in a function. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eduard Staniloiu | 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
|
Copyright © 1999-2021 by the D Language Foundation