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

Reply via email to