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