On 12/21/11 17:42, Kagamin wrote:
>> Could you elaborate?
> 
> As I remember, these features rely heavily on linker support, namely on how 
> it merges sections. Each pointer to static ctor (and unittest) is placed in a 
> section, then these sections are merged by linker and you get an array of 
> pointers to all static ctors and unittests. The startup code reads the 
> pointers in sequence and executes them. If some section is removed, the 
> corresponding static ctor won't be run.
> 
>> Real code, that i was testing with previously, contained static module ctors 
>> which
>> worked, and i just tried a simple two module test w/ multiple 
>> shared_[cd]tors +
>> static_[cd]tors + unittests -- all of them are called as expected.
> 
> If so then ok.

I suspected that was what you were worried about and did that test [1],
which gives the expected output. But looking now at the list of linker
gc'ed sections, i notice ld does claim to have removed eg
".text._D11gcfuncdata218_sharedStaticCtor3FZv", which is one of the ctors.
The reason things still work is because the code is also inlined in 
"_D11gcfuncdata215__modsharedctorFZv" together with the other ctor. 
Aha, the compiler (gdc) actually inlined all the [cd]tors when run at -O3,
and the "real" constructor was then garbage collected by the linker. Phew.
Compiling with -O2 makes modsharedctor call all the ctors instead, and they
are then not gc'ed. 

Why the compiler emits the unused outofline ctors is another question.
Maybe i should start marking them as private?...

Turned out not to be a good idea, as the compiler silently accepts
"shared private static this() {...}" and does not emit the dead code anymore.
But.. this constructor is run together with the un-shared ones, ie possibly
_after_ them... (this is not section-gc specific, happens w/o it too)

artur

[1]

import std.stdio;

/* gcfuncdata2.d is a copy of this module, w/o main() */
import gcfuncdata2;

auto p(S...)(S args) { return stdout.writeln(__FILE__~": ", args); }

void main(string[] args){ p("main"); }

static this() { p("ctor1"); }
static this() { p("ctor2"); }
shared static this() { p("shared ctor1"); }
shared static this() { p("shared ctor2"); }

static ~this() { p("dtor1"); }
static ~this() { p("dtor2"); }
shared static ~this() { p("shared dtor1"); }
shared static ~this() { p("shared dtor2"); }

unittest { p("unittest1"); }
unittest { p("unittest2"); }

Reply via email to