immutable, static, __gshared, TLS, and compile time allocation
Walter Bright
newshound2 at digitalmars.com
Fri Apr 20 18:10:34 PDT 2012
On 4/20/2012 1:45 PM, Manu wrote:
> static int x; <- this is... a 'static' global instance, whatever that means?
At global scope, the 'static' attribute is redundant and therefore meaningless.
> Is this TLS or not?
static int x; // TLS
> If so, how is it distinct from 'int x;' above?
At global scope, it is the same.
> I presume it
> must still be TLS, and effectively meaningless at the global scope; dlang.org
> <http://dlang.org> states "static is ignored when applied to other
> declarations". It is just used for members of struct/classes? Why not produce a
> syntax error rather than ignore it?
Originally, it meant 'private' at global scope, but this was dropped.
> immutable int x; <- this can't possibly change, so why would it be TLS?
It wouldn't be TLS, because as you said, it can't change.
> it must be a single static instance... right?
Right. But this is an optimization - semantically, it makes no difference if it
is TLS or not.
> __gshared int x; <- this should behave exactly like a C global right? ie, no TLS
> + addressable at compile time.
Yes.
> static immutable x; <- i've seen this a few times, what does it mean?
At global scope, it means: immutable x;
> I'm concerned with which of these are addressable at compile time. By my logic,
> all (well, perhaps not the first) should be allocated in the datablock,
> addresses known at compile time, and therefore addressable at compile time (ie,
> able to alias in template args).
This is a misunderstanding of alias. Alias does not mean "has a compile time
pointer to it", it means it is a symbol.
> That doesn't seem to be the case however in at least the __gshared case (in my
> big report above), which is very surprising to me.
>
> There's another thing that that's had me scratching my head for a while, and
> gave me the contradictory feeling that the use of TLS data is fairly relaxed:
>
> struct S
> {
> int x;
> static int y;
> }
>
> In this case y is static, ie, globally shared by all instances,
y would be TLS.
> but I expect it SHOULD be TLS,
and it is.
> since it is mutable, and therefore not thread safe...
> That said, I write code that passes static members of structs into templates as
> alias parameters all the time, and generate code that writes to them.
> How is this possible? And given that it is, why is it not possible for at least
> __gshared at global scope?
Because alias is a symbolic alias, not a compile time address.
> struct S
> {
> static x;
> __gshared y;
> }
>
> What is the difference between x and y here?
x is TLS, y is in the global data segment.
> I've obviously missed something rather fundamental, but the dlang descriptions
> of each of these attributes are a little light, and leaves me quite unclear on
> the details here.
>
> I'm particularly confused that I CAN alias a static member in a struct, which I
> suspect should be TLS for thread safety, but I CAN'T alias a __gshared at global
> scope, which is not TLS by definition?
You can alias a global __gshared symbol, you just cannot alias an offset into a
symbol (i.e. a computation on a symbol).
More information about the Digitalmars-d
mailing list