Thread overview
Static constructors in structs.
Oct 30, 2015
TheFlyingFiddle
Oct 30, 2015
anonymous
Oct 30, 2015
TheFlyingFiddle
Oct 30, 2015
BBasile
Oct 30, 2015
BBasile
Oct 30, 2015
TheFlyingFiddle
Oct 31, 2015
Adam D. Ruppe
Oct 30, 2015
Adam D. Ruppe
Oct 30, 2015
TheFlyingFiddle
October 30, 2015
Is this intended to work?

struct A
{
   __gshared static this()
   {
      //Add some reflection info to some global stuff.
      addReflectionInfo!(typeof(this));
   }
}

I just noticed this works in 2.069, is this intended? I mean I love it! It makes it possible to do lot's of useful mixins for runtime reflection for example. Just wondering if I can start writing code this way or if it's a regression and is going away. I think this did not work a year ago when I tried doing something like this.
October 30, 2015
On 30.10.2015 21:23, TheFlyingFiddle wrote:
> Is this intended to work?
>
> struct A
> {
>     __gshared static this()
>     {
>        //Add some reflection info to some global stuff.
>        addReflectionInfo!(typeof(this));
>     }
> }
>
> I just noticed this works in 2.069, is this intended?

static constructors are supposed to work, yes.

The description is on the class page: http://dlang.org/class.html#static-constructor

__gshared doesn't do anything there, though. Use `shared static this` instead, if you want the constructor to run only once per process, and not once per thread.
October 30, 2015
On Friday, 30 October 2015 at 20:23:45 UTC, TheFlyingFiddle wrote:
> I just noticed this works in 2.069, is this intended?

I thought it always worked. The __gshared there I'm pretty sure doesn't do anything and should prolly be removed.

The two forms are `static this` which is called for each thread and `shared static this` which is only called once per process. The compiler literally looks for the sequence of keywords there, so they need to be exactly in that order.

But yeah, the struct feature table http://dlang.org/struct.html shows them as checked.
October 30, 2015
On Friday, 30 October 2015 at 20:58:37 UTC, anonymous wrote:
> On 30.10.2015 21:23, TheFlyingFiddle wrote:
>> Is this intended to work?
>>
>> struct A
>> {
>>     __gshared static this()
>>     {
>>        //Add some reflection info to some global stuff.
>>        addReflectionInfo!(typeof(this));
>>     }
>> }
>>
>> I just noticed this works in 2.069, is this intended?
>
> static constructors are supposed to work, yes.
>
> The description is on the class page: http://dlang.org/class.html#static-constructor
>
> __gshared doesn't do anything there, though. Use `shared static this` instead, if you want the constructor to run only once per process, and not once per thread.

Was under the impression that __gshared did the same thing for static constructors. Thanks.
October 30, 2015
On Friday, 30 October 2015 at 20:59:46 UTC, Adam D. Ruppe wrote:
> On Friday, 30 October 2015 at 20:23:45 UTC, TheFlyingFiddle wrote:
> But yeah, the struct feature table http://dlang.org/struct.html shows them as checked.

I gotta say the language documentation is shaping up nicely.
October 30, 2015
On Friday, 30 October 2015 at 20:58:37 UTC, anonymous wrote:
> On 30.10.2015 21:23, TheFlyingFiddle wrote:
>> Is this intended to work?
>>
>> struct A
>> {
>>     __gshared static this()
>>     {
>>        //Add some reflection info to some global stuff.
>>        addReflectionInfo!(typeof(this));
>>     }
>> }
>>
>> I just noticed this works in 2.069, is this intended?
>
> static constructors are supposed to work, yes.
>
> The description is on the class page: http://dlang.org/class.html#static-constructor
>
> __gshared doesn't do anything there, though. Use `shared static this` instead, if you want the constructor to run only once per process, and not once per thread.

__gshared is mostly usefull on fields (eg public uint a) because it prevents a data to be put on the TLS, which in certain case reduces the perfs up to 30%. The byte code using a global variable that's not __gshared can be incredibly slower !
October 30, 2015
On Friday, 30 October 2015 at 21:29:22 UTC, BBasile wrote:
> On Friday, 30 October 2015 at 20:58:37 UTC, anonymous wrote:
>> On 30.10.2015 21:23, TheFlyingFiddle wrote:
>>> Is this intended to work?
>>>
>>> struct A
>>> {
>>>     __gshared static this()
>>>     {
>>>        //Add some reflection info to some global stuff.
>>>        addReflectionInfo!(typeof(this));
>>>     }
>>> }
>>>
>>> I just noticed this works in 2.069, is this intended?
>>
>> static constructors are supposed to work, yes.
>>
>> The description is on the class page: http://dlang.org/class.html#static-constructor
>>
>> __gshared doesn't do anything there, though. Use `shared static this` instead, if you want the constructor to run only once per process, and not once per thread.
>
> __gshared is mostly usefull on fields (eg public uint a) because it prevents a data to be put on the TLS, which in certain case reduces the perfs up to 30%. The byte code using a global variable that's not __gshared can be incredibly slower !

Im' talking about DMD win32 BTW. Even if now I've switched to full time linux, I have a test on the hold HDD that demonstrates this :). That's really uncredible. Avoid TLS as possible on DMD with the switch "-vtls".
October 30, 2015
On Friday, 30 October 2015 at 21:29:22 UTC, BBasile wrote:
> __gshared is mostly usefull on fields (eg public uint a) because it prevents a data to be put on the TLS, which in certain case reduces the perfs up to 30%. The byte code using a global variable that's not __gshared can be incredibly slower !

I have gotten used to using __gshared on fields so much that I just naturally assumed that shared static this() { } would be equivalent to __gshared static this() { } :P. I find they can be very useful for data that initialized in static constructors and then never change again (I will have to fix my shared constructors now :S guess i have been lucky not running into race problems before).
October 31, 2015
On Friday, 30 October 2015 at 21:29:22 UTC, BBasile wrote:
> __gshared is mostly usefull on fields (eg public uint a)

That's only true if it is at the module level or static. Ordinary struct members are whatever the container is and class members are on the heap unless you do something fancy.

module test;

int tls; // this is in tls
shared(int) s; // this is not TLS
__gshared int s; // also not TLS, same as shared(), but doesn't change the type

struct Foo {
   int var; // will be TLS only is the instance is TLS
   static int tls; // put in TLS
   shared(int) s; // not TLS
   __gshared int s; // also not TLS
}

class Foo {
   int var; // not TLS unless you do some weird allocation scheme
   static int tls; // TLS
   // you get the idea now
}

> because it prevents a data to be put on the TLS, which in certain case reduces the perfs up to 30%. The byte code using a global variable that's not __gshared can be incredibly slower !

right, TLS has some cost but it has benefits too. Best performance is often gotten by not using globals much at all - try to get a local copy on the stack to work with. Then you will more likely be in the CPU cache and can see enormous speedups.