www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static constructors guaranteed to run?

reply "Tofu Ninja" <emmons0 purdue.edu> writes:
Are static constructors guaranteed to run if the module is 
imported? Also are static constructors in templated types 
guaranteed to run for every instantiation? Even if the 
instantiation is never actually used outside of compile time 
code, like in an alias or in a UDA?
Jun 26 2015
next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Friday, 26 June 2015 at 22:00:54 UTC, Tofu Ninja wrote:
 Are static constructors guaranteed to run if the module is 
 imported?
AFAIK, yes.
 Also are static constructors in templated types guaranteed to 
 run for every instantiation? Even if the instantiation is never 
 actually used outside of compile time code, like in an alias or 
 in a UDA?
Definitely not. Things inside a template don't even exist if that template is never instantiated.
Jun 27 2015
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/27/2015 11:54 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= 
<schuetzm gmx.net>" wrote:
 Also are static constructors in templated types guaranteed to run for
 every instantiation? Even if the instantiation is never actually used
 outside of compile time code, like in an alias or in a UDA?
Definitely not. Things inside a template don't even exist if that template is never instantiated.
(That wasn't his question.)
Jun 27 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Saturday, 27 June 2015 at 20:16:10 UTC, Timon Gehr wrote:
 On 06/27/2015 11:54 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= 
 <schuetzm gmx.net>" wrote:
 Also are static constructors in templated types guaranteed to 
 run for
 every instantiation? Even if the instantiation is never 
 actually used
 outside of compile time code, like in an alias or in a UDA?
Definitely not. Things inside a template don't even exist if that template is never instantiated.
(That wasn't his question.)
Ah sorry, I see. In this case I don't know the answer. There might even be a difference between normal CTFE code and is-expressions...
Jun 28 2015
prev sibling next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Fri, 26 Jun 2015 22:00:51 +0000, Tofu Ninja wrote:

 Are static constructors guaranteed to run if the module is imported?
 Also are static constructors in templated types guaranteed to run for
 every instantiation? Even if the instantiation is never actually used
 outside of compile time code, like in an alias or in a UDA?
i believe that the answers are: 1. yes. 2. no. =
Jun 27 2015
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
Hmm... any reason why?
Jun 27 2015
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
=20 Hmm... any reason why?
if instantiated template was not used in any code that makes into=20 compiled binary, compiler is free to remove it with all it's ctors. it=20 may do that, or may not, but removal is allowed. so while that can work=20 now (i didn't checked), it may stop working in next version (or with=20 another compiler), and that will not be a bug.=
Jun 28 2015
next sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Monday, 29 June 2015 at 02:07:57 UTC, ketmar wrote:
 On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
Hmm... any reason why?
if instantiated template was not used in any code that makes into compiled binary, compiler is free to remove it with all it's ctors. it may do that, or may not, but removal is allowed. so while that can work now (i didn't checked), it may stop working in next version (or with another compiler), and that will not be a bug.
Can you say the same about non templated static constructors? Like if a type is never used but it has a static constructor, is the compiler free to remove that as well?
Jun 28 2015
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 29 Jun 2015 02:19:54 +0000, Tofu Ninja wrote:

 On Monday, 29 June 2015 at 02:07:57 UTC, ketmar wrote:
 On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
=20 Hmm... any reason why?
if instantiated template was not used in any code that makes into compiled binary, compiler is free to remove it with all it's ctors. it may do that, or may not, but removal is allowed. so while that can work now (i didn't checked), it may stop working in next version (or with another compiler), and that will not be a bug.
=20 Can you say the same about non templated static constructors? Like if a type is never used but it has a static constructor, is the compiler free to remove that as well?
yes. it doesn't do that now, afair, but i can't see any sense in running=20 code that obviously does nothing, as it's owner is not used. module ctors=20 was designed for such things -- i.e. to run some code on startup. if=20 someone is doing some vital initialization in static ctor of struct or=20 class, and that struct or class aren't used anywhere else in his code,=20 he's doing it wrong. it *may* work now, but that's simply 'cause compiler=20 is not very well at removing unused code.=
Jun 28 2015
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Monday, 29 June 2015 at 02:31:18 UTC, ketmar wrote:
 yes. it doesn't do that now, afair, but i can't see any sense 
 in running code that obviously does nothing, as it's owner is 
 not used. module ctors was designed for such things -- i.e. to 
 run some code on startup. if someone is doing some vital 
 initialization in static ctor of struct or class, and that 
 struct or class aren't used anywhere else in his code, he's 
 doing it wrong. it *may* work now, but that's simply 'cause 
 compiler is not very well at removing unused code.
That seems wrong, what if I am doing separate compilation, how would the compiler know if the type is going to be used or not...
Jun 28 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 29 Jun 2015 03:10:44 +0000, Tofu Ninja wrote:

 On Monday, 29 June 2015 at 02:31:18 UTC, ketmar wrote:
 yes. it doesn't do that now, afair, but i can't see any sense in
 running code that obviously does nothing, as it's owner is not used.
 module ctors was designed for such things -- i.e. to run some code on
 startup. if someone is doing some vital initialization in static ctor
 of struct or class, and that struct or class aren't used anywhere else
 in his code, he's doing it wrong. it *may* work now, but that's simply
 'cause compiler is not very well at removing unused code.
=20 That seems wrong, what if I am doing separate compilation, how would the compiler know if the type is going to be used or not...
it doesn't really matter if you compiled your code separate or not:=20 compiler *has* to know everything to successfully link the program. and=20 it knows. for now it doesn't do much with that info, though, as using=20 binutils for languages like D sux: D needs it's own compiled module=20 format and optimising linker. but as i told ealier, this is the limitiation of current implementation,=20 not guarantee.=
Jun 28 2015
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
p.s. also note that module can has several static ctors, i.e. this works=20
fine:

=3D=3D=3D z00.d =3D=3D=3D

module z00;

import std.stdio;

static this () { writeln("ctor0"); }

static this () { writeln("ctor1"); }


=3D=3D=3D z01.d =3D=3D=3D

module z01;

import z00;

void main () {}


this prints:
ctor0
ctor1


so you can several initialization functions to module with, for example,=20
mixins.=
Jun 28 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 29 June 2015 at 02:07:57 UTC, ketmar wrote:
 On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
Hmm... any reason why?
if instantiated template was not used in any code that makes into compiled binary, compiler is free to remove it with all it's ctors. it may do that, or may not, but removal is allowed. so while that can work now (i didn't checked), it may stop working in next version (or with another compiler), and that will not be a bug.
Does the specification really say that? This isn't obvious to me at all. I would expect static ctors to be treated as if they were "referenced" by the initialization logic (though I understand it's not an explicit reference, they just end up in a special section that the runtime can inspect).
Jun 29 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 29 Jun 2015 10:19:33 +0000, Marc Sch=C3=BCtz wrote:

 On Monday, 29 June 2015 at 02:07:57 UTC, ketmar wrote:
 On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
=20 Hmm... any reason why?
if instantiated template was not used in any code that makes into compiled binary, compiler is free to remove it with all it's ctors. it may do that, or may not, but removal is allowed. so while that can work now (i didn't checked), it may stop working in next version (or with another compiler), and that will not be a bug.
=20 Does the specification really say that? This isn't obvious to me at all. I would expect static ctors to be treated as if they were "referenced" by the initialization logic (though I understand it's not an explicit reference, they just end up in a special section that the runtime can inspect).
it doesn't, afair, but it's quite natural. if user type was throwed out=20 as unused, it would be very strange to insist on keeping it's=20 initialization code.=
Jun 29 2015
next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 29 June 2015 at 11:36:42 UTC, ketmar wrote:
 it doesn't, afair, but it's quite natural. if user type was 
 throwed out as unused, it would be very strange to insist on 
 keeping it's initialization code.
Yes, but I would instead expect that the static ctor prevents the type from becoming unused in the first place.
Jun 29 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 29 Jun 2015 17:22:17 +0000, Marc Sch=C3=BCtz wrote:

 On Monday, 29 June 2015 at 11:36:42 UTC, ketmar wrote:
 it doesn't, afair, but it's quite natural. if user type was throwed out
 as unused, it would be very strange to insist on keeping it's
 initialization code.
=20 Yes, but I would instead expect that the static ctor prevents the type from becoming unused in the first place.
and i expect it to be thrown away. ;-) as we have module-scope static=20 ctors to initialize various things that should be always initialized. and=20 type static ctor -- by my logic deduction -- should only initialize=20 internal type fields. and why should i even bother to initialize that=20 internal fields if the type is not used anywhere?=
Jul 01 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 1 July 2015 at 07:55:20 UTC, ketmar wrote:
 On Mon, 29 Jun 2015 17:22:17 +0000, Marc Schütz wrote:

 On Monday, 29 June 2015 at 11:36:42 UTC, ketmar wrote:
 it doesn't, afair, but it's quite natural. if user type was 
 throwed out as unused, it would be very strange to insist on 
 keeping it's initialization code.
Yes, but I would instead expect that the static ctor prevents the type from becoming unused in the first place.
and i expect it to be thrown away. ;-) as we have module-scope static ctors to initialize various things that should be always initialized. and type static ctor -- by my logic deduction -- should only initialize internal type fields. and why should i even bother to initialize that internal fields if the type is not used anywhere?
The behaviour you expect makes more sense, for sure, but I was trying to guess what the current implementation might be doing without actually having to try it :-)
Jul 01 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Wed, 01 Jul 2015 09:42:31 +0000, Marc Sch=C3=BCtz wrote:

 The behaviour you expect makes more sense, for sure, but I was trying to
 guess what the current implementation might be doing without actually
 having to try it :-)
ah, sorry. i was talking about "the ideal case with ideal compiler", not=20 about current state of things. ;-)=
Jul 01 2015
prev sibling parent "Tofu Ninja" <emmons0 purdue.edu> writes:
On Monday, 29 June 2015 at 11:36:42 UTC, ketmar wrote:
 it doesn't, afair, but it's quite natural. if user type was 
 throwed out as unused, it would be very strange to insist on 
 keeping it's initialization code.
Personally I would be kinda pissed if the compiler did this, I expect the static ctor to run, even if I don't use the type.
Jun 29 2015
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Sat, 27 Jun 2015 22:49:13 +0000, Tofu Ninja wrote:

 On Saturday, 27 June 2015 at 22:20:40 UTC, ketmar wrote:
 2. no.
=20 Hmm... any reason why?
p.s. note that static ctors are *intended* to run in runtime, not in=20 compile time. if compiler decides that some code is not required in=20 runtime, it is free to remove all that code, including static ctors.=
Jun 28 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/26/15 6:00 PM, Tofu Ninja wrote:
 Also are static constructors in templated types guaranteed to run for
 every instantiation?
I'd hazard to guess that the current compiler does run them, but that they probably aren't guaranteed to run by a sufficiently smart future compiler. Note, I strongly would discourage having static ctors inside templates: https://issues.dlang.org/show_bug.cgi?id=14517 -Steve
Jun 30 2015