digitalmars.D.learn - Is it possible to modify shared struct array in a function.
- Sudhi (40/40) Feb 07 2019 I have a situation, where i want to modify a shared variable in a
- Arun Chandrasekaran (3/43) Feb 07 2019 Works fine for me with DMD64 D Compiler v2.083.1.
- Sudhi (39/93) Feb 07 2019 My example code was wrong. Below is the right one.
- Arun Chandrasekaran (3/43) Feb 07 2019 `shared struct Metadata` should make it work.
- Jerry (7/51) Feb 07 2019 You have to cast away shared:
- Eduard Staniloiu (30/91) Feb 08 2019 You do not need to cast away shared. You had a couple of issues
- Jonathan M Davis (10/116) Feb 08 2019 Honestly, the fact that that code compiles is a bug. You're not supposed...
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
Feb 07 2019
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, SudhiWorks fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU
Feb 07 2019
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: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/iem0PYI 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, SudhiWorks fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU
Feb 07 2019
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:`shared struct Metadata` should make it work. Turtles (shared) all the way down.[...]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
Feb 07 2019
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: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.On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi 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[...]Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU
Feb 07 2019
On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote:On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: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, EdiOn Friday, 8 February 2019 at 04:30:23 UTC, Arun Chandrasekaran wrote: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.On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi 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[...]Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU
Feb 08 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: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 DavisOn Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: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, EdiOn Friday, 8 February 2019 at 04:30:23 UTC, Arun Chandrasekaran wrote: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.On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi 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[...]Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU
Feb 08 2019