Fixing cyclic import static construction problems

Artur Skawina art.08.09 at gmail.com
Sat Dec 1 02:53:21 PST 2012


On 11/30/12 21:40, Jonathan M Davis wrote:
> On Friday, November 30, 2012 10:27:31 Artur Skawina wrote:
>> On 11/29/12 23:34, Jonathan M Davis wrote:
>>> On Thursday, November 29, 2012 23:28:07 Timon Gehr wrote:
>>>> On 11/29/2012 01:17 PM, Jonathan M Davis wrote:
>>>>> In the past when I've brought up similar solutions, he's been completely
>>>>> opposed to them. ...
>>>>
>>>> It is not a solution, it is a workaround.
>>>
>>> What do you mean? The runtime sees circular dependencies between modules
>>> even when there's no actual circular dependency between static
>>> constructors. We need to fix that. One way is to just make the runtime
>>> not care, which wouldn't be particularly safe. Another is to explicitly
>>> tell it that there are no such dependencies. I don't see how that's not a
>>> solution. And unless someone can come up with a way for the runtime to
>>> somehow determine on its own that there's no actual, circular dependency,
>>> I don't see how anything better could be done.
>>
>> It's relatively easy for the /compiler/ to figure it out; it's just that
>> implementing a simple user-provided flag requires the least amount of work.
>> What Walter suggested can be tweaked to be sane (per-ctor flag) and will
>> still be useful if/when the compiler becomes smarter (think lazily initted
>> module fields).
>> For the compiler to check if the value of every imported symbol accessed
>> inside a mod-ctor can be evaluated at compile-time (if you encounter a case
>> where this is not true it means there (potentially) is a true dependency and
>> the ctors should be ordered) would require more work.
> 
> It can't be evaluated at compile time because of .di files. The compiler 

It can. The case where all definitions aren't available is of course a potential
source of cycles and means that the ctors have to be run in order. There's no
way around that, and it's where the attribute (nee pragma) helps, because it can
be attached to the declaration, when the programmer thinks he knows better.

Andrei's naive suggestion would only handle the trivial toy example case, but
fail for much of real code, that needs to access statically known properties of
other modules. D has enough features that work for five-liners, but are unusable
for real work.

The important points are that:

1) a ctor that does not access any symbol from another module is not treated
   as dependent on that module.
2) accessing just /types/ defined in another module works. No RT dep here.
3) reading known initialized constant data works. That's const/immutable/enum -
   again, those can never become a RT dep.
4) calling side-effect free code that does not depend on non-local state works.
   This is why an is-it-ctfeable check works - it will catch even the indirect deps.
   Yeah, it's conservative, but is has to be. A kind of 'pure-but-w/o-external-refs"
   thing would help further, but that can be added incrementally and may not even
   be necessary.   

> have nothing even close to that. Regardless, while the compiler may be able
> to provide additional information to the runtime, it's still the runtime that
> needs to figure this out and not the compiler.

No. Would, at least, require going from per-module to per-symbol which is a *much*
larger change than was proposed here. I don't even want to think about the (runtime)
cost.

artur


More information about the Digitalmars-d mailing list