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