Proposal to make "shared" (more) useful

Arafel er.krali at gmail.com
Thu Sep 13 15:49:38 UTC 2018


On 09/13/2018 05:11 PM, Adam D. Ruppe wrote:
> On Thursday, 13 September 2018 at 14:43:51 UTC, Arafel wrote:
>>  Why must __gshared be static?? (BTW, thanks a lot, you have just 
>> saved me a lot of debugging!!).
> 
> The memory location differences of shared doesn't apply to class 
> members. All members are stored with the instance, and shared only 
> changes the type. (Contrast to global variables, where shared changes 
> where they are stored - the default is to put them in thread-local 
> storage, and shared moves it back out of that.)
> 
> Class static variables btw follow the same TLS rules. A static member is 
> really the same as a global thing, just in a different namespace.
> 
> 
> Now, the rule of __gshared is it puts it in that global memory storage 
> using the unshared type. Unshared type you like here, but also, since 
> normally, class members are stored in the object, changing the memory 
> storage to the global shared area means it is no longer with the 
> object... thus it becomes static.
> 
>> Then, how on earth are we supposed to have a struct like SysTime as a 
>> field in a shared class? Other than the "fun" of having a shared 
>> *pointer* to such a struct that then you can cast as non-shared as 
>> needed...
> 
> What you want is an unshared type without changing the memory layout. 
> There's no syntax for this at declaration, but there is one at usage 
> point: you can cast away attributes on an lvalue:
> 
> shared class Foo {
>          void update() {
>                  // the cast below strips it of all attributes, 
> including shared,
>                  // allowing the assignment to succeed
>                  cast() s = Clock.currTime;
>          }
>          SysTime s;
> }
> 
> 
> 
> Using the private field with a public/protected/whatever accessor 
> method, you can encapsulate this assignment a little and make it more 
> sane to the outside world.

Thanks a lot!! I remember having tried casting shared away, and ending 
up with a duplicate, but I have just tried it now and indeed it seems to 
work, will have to try with more complex use cases (comparing, adding 
dates and intervals, etc.), but it looks promising.

The problem might have been that I think I tried:

shared SysTime s_;
SysTime s = cast () s_; // Now I've got a duplicate! Ugh!

Because that works with classes... but (in hindsight) obviously not with 
value types.

I still think that it would be useful:

1) Allow __gshared for non-static fields to have this meaning, it would 
make it much more intuitive. A library solution is perhaps possible, but 
cumbersome.

2) Make it (sometimes) automatic as the original proposal.

Of course 1) is the most important part.

A.


More information about the Digitalmars-d mailing list