immutable, static, __gshared, TLS, and compile time allocation

Jonathan M Davis jmdavisProg at gmx.com
Fri Apr 20 14:05:54 PDT 2012


On Friday, April 20, 2012 23:45:11 Manu wrote:
> I need to clarify some things that have confused me a few times. I've
> reconsidered these basic attributes a few times, and I thought I understood
> them, but I obviously don't.
> 
> The case that has confused me is here:
> http://d.puremagic.com/issues/show_bug.cgi?id=7897
> 
> In the global scope:
> 
> int x; <- x is TLS
> 
> but:
> 
> static int x; <- this is... a 'static' global instance, whatever that
> means? Is this TLS or not? If so, how is it distinct from 'int x;' above? I
> presume it must still be TLS, and effectively meaningless at the global
> scope; 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?

Attributes get ignored all over the place in D. There's at least one bug 
report, on it:

http://d.puremagic.com/issues/show_bug.cgi?id=3934

Whether that'll change or not, I don't know, since it's not clear that Walter 
considers it to be a problem from what I recall about his comments on 
discussions on it.

> immutable int x; <- this can't possibly change, so why would it be TLS? it
> must be a single static instance... right?

immutable is implicitly shared.

> __gshared int x; <- this should behave exactly like a C global right? ie,
> no TLS + addressable at compile time.

I believe so, yes.

> static immutable x; <- i've seen this a few times, what does it mean?

Assuming that static is valid in that context, it means that you have a static 
variable which is immutable. If it's not valid (e.g. module-level variable), 
then it's just an immutable variable. In either case, because it's immutable, 
it's implicitly shared.

> 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, but I
> expect it SHOULD be TLS, 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?

I don't understand the problem. y is static, so there's a single instance for 
it for the class per thread, whereas each instance of S will have its own x. I 
think that I'd have to see actual code to understand exactly what your issue 
is with regard to templates.

> struct S
> {
> static x;
> __gshared y;
> }
> 
> What is the difference between x and y here?

x is in TLS, so there's one instance per thread. I'm not quite sure whether 
__gshared does anything here though, since it's a member variable rather than 
a class variable or module-level variable. I expect that __gshared is ignored 
here, but I don't know. If you had

struct S
{
 static x;
 static __gshared y;
}

then there would be one instance of y for the entire program, but it wouldn't 
be protected in the same way that it would be if it were shared.

> 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.

Yeah. The documentation in general tends to be a bit light, and this is 
definitely one area where it could use some fleshing out.

- Jonathan M Davis


More information about the Digitalmars-d mailing list