Cyclic dependencies vs static constructors

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Dec 19 22:56:11 UTC 2017


On Tuesday, December 19, 2017 16:09:41 Steven Schveighoffer via Digitalmars-
d wrote:
> On 12/19/17 2:04 PM, Jonathan M Davis wrote:
> > The fact that static constructors can't properly handle circular
> > dependencies does mean that there's a tendancy to throw them under the
> > bus at some point, which can be a serious problem. Andrei has been
> > jumping through all kinds of insane hoops recently in an attempt to
> > remove all static constructors from Phobos, which is going a bit far
> > IMHO, but that's open for debate, and if the result works properly, I
> > don't know how much I care, though I'm disinclined to jump through
> > those sort of hoops in my own code.
>
> But that's not because of circular dependencies, that's to allow those
> pieces of phobos to be independent of druntime.
>
> However, it does (as a side effect) eliminate the need for proper
> construction order, at the cost of more expensive access to the global
> data.

Either way, it's bending over backwards to avoid a language feature that's
supposed to perfectly fine to use. And I confess that I'm getting a bit
tired of the stuff in druntime or Phobos being contorted to avoid certain
language features just to satisfy some of the more extreme segments of the
community.

> > In the past, I suggested that we have some sort of attribute for a
> > static
> > constructor that tells the compiler and runtime that there isn't really
> > a
> > circular dependency - either by indicating that it isn't circularly
> > dependent on anything or by telling it what the dependency order is so
> > that the load order for the modules can be dealt with correctly - but
> > Walter rejected the idea on the grounds that it was too risky. Not only
> > would it be easy to get wrong to begin with, but if the code changed
> > later, actual, circular dependencies could go unnoticed and result in
> > some pretty nasty bugs.
>
> But this doesn't even solve the problem of decoupling the grouping of
> types/data into a related module from the problem of static
> construction. That is, you may import other modules for reasons totally
> separate from static construction.

Having an attribute to kill the circular dependency complaint would solve
the case where we have something like std/stdiobase.d with a static
constructor calling a function that has the actual static constructor code -
and it would do so without sacrificing the ability to do stuff like
initialize immutable variables. I don't think that it would really solve
anything beyond that. A "perfect" solution would involve the compiler and
runtime figuring out the exact order to run static constructors in spite of
the circular imports and only complaining when it's actually not possible to
order them correctly, because they're truly circularly dependent, but
unfortunately, that's really too hard to do, and as annoying as the current
solution is, it's arguably a good solution given the constraints.

> The only idea I had that makes things a bit better is to ignore imports
> inside unit tests (since those are only ever run after static
> construction anyway).
>
> Maybe there are some other ways to do it. But none of them are going to
> be painless.

Yeah, I don't know. It might also be possible to figure something out based
on which imports are local, but I'm not sure. It wouldn't take much for even
a moderate improvement to get way too complicated to be feasible.

- Jonathan M Davis



More information about the Digitalmars-d mailing list