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.