Program size, linking matter, and static this()

Timon Gehr timon.gehr at gmx.ch
Fri Dec 16 13:41:14 PST 2011


On 12/16/2011 09:31 PM, Jonathan M Davis wrote:
> On Friday, December 16, 2011 21:06:49 Timon Gehr wrote:
>> On 12/16/2011 08:41 PM, Jonathan M Davis wrote:
>>> On Friday, December 16, 2011 12:29:18 Andrei Alexandrescu wrote:
>>>> Jonathan, could I impose on you to replace all static cdtors in
>>>> std.datetime with lazy initialization? I looked through it and it
>>>> strikes me as a reasonably simple job, but I think you'd know better
>>>> what to do than me.
>>>>
>>>> A similar effort could be conducted to reduce or eliminate static
>>>> cdtors
>>>> from druntime. I made the experiment of commenting them all, and that
>>>> reduced the size of the baseline from 218KB to 200KB. This is a good
>>>> amount, but not as dramatic as what we can get by working on
>>>> std.datetime.>
>>> Hmm. I had reply for this already, but it seems to have disappeared, so
>>> I'll try again.
>>>
>>> You could make core.time use property functions instead of the static
>>> immutable variables that it's using now for ticksPerSec and appOrigin,
>>> but in order to do that right would require introducing a mutex or
>>> synchronized block (which is really just a mutex under the hood
>>> anyway), and I'm loathe to do that in time-related code. ticksPerSec
>>> gets used all over the place in TickDuration, and that could have a
>>> negative impact on performance for something that needs to be really
>>> fast (since it's used in stuff like StopWatch and benchmarking). On top
>>> of that, in order to maintain the current semantics, the property
>>> functions would have to be pure, which they can't be without doing some
>>> nasty casting to convince the compiler that stuff which isn't pure is
>>> actually pure.
>>
>> lazy variables would resolve this.
>
> True, but we don't have them.
>
>> Circular dependencies are not to be blamed on the design of static
>> constructors.
>
> Yes they are.

No. They arise from the design of the module hierarchy.

> static constructors completely chicken out on them. Not only is
> there no real attempt to determine whether the static constructors are
> actually dependent (which granted, isn't an easy problem),

I don't think that is an option.

> but there is _zero_ support in the language for resolving such circular dependencies. There's no
> way to say that they _aren't_ dependent even if you can clearly see that they
> aren't.

Yes there is. The compiler and runtime understand that they are not 
mutually dependent if their modules are not mutually dependent. Package 
level is the right level for dealing with such issues because the 
circular dependencies are a modularity problem.

> The solution used in Phobos (which won't work in std.datetime due to
> the use of immutable and pure) is to create a C module which has the code from
> the static constructor and then have a separate module which calls it in its
> static constructor.

You don't need a C function if you just factor out every variable it 
initializes to the separate D module. __fileinit.d works that way. I 
don't see why stdiobase.d could not do the same.

> It works, but it's not pretty (and it doesn't always work
> - e.g. std.datetime), and it would be _far_ better if you could just mark a
> static constructor as not depending on anything or mark it as not depending on
> a specific module or something similar.

How would that be checked?

> And given how disgusting it generally
> is to even figure out what's causing a circular dependency when the runtime
> won't start your program because of it, I really think that this is a problem
> which should resolved. static constructors need to be improved.
>

Nobody has figured out how to solve the problem of modular global data 
initialization. That is because there probably is no solution.

>>> In general at this point, it's looking like
>>> static constructors are turning out to be a bit of a failure on some
>>> level, given the issues that we're having because of them, and I think
>>> that we should fix the language and/or compiler so that they _aren't_ a
>>> failure.
>>>
>>> - Jonathan M Davis
>>
>> We are having (minor!!) problems because the task of initializing global
>> data in a modular way is inherently hard.
>>
>> Just have a look how other languages handle initialization of global
>> data and you'll notice that the D solution is actually very sensible.
>
> Yes. The situation with D is better than that of many other languages, but
> what prodblems we do have can be _really_ annoying to deal with. Have to deal
> with circular dependencies due to static module constructors which aren't
> actually interdependent is one of the most annoying issues in D IMHO.
>

Adding a language construct that turns off the checking entirely (as you 
seem to suggest) is not at all better than having to create a few 
additional source files.





More information about the Digitalmars-d mailing list