Is Anything Holding you back?

Johannes Pfau via Digitalmars-d digitalmars-d at puremagic.com
Wed Oct 7 07:59:36 PDT 2015


Am Wed, 07 Oct 2015 10:50:38 +0000
schrieb Jonathan M Davis <jmdavisProg at gmx.com>:

> On Wednesday, 7 October 2015 at 10:03:11 UTC, Johannes Pfau wrote:
> > Am Wed, 07 Oct 2015 08:41:30 +0000
> > schrieb Jonathan M Davis <jmdavisProg at gmx.com>:
> >
> >> On Wednesday, 7 October 2015 at 07:08:39 UTC, extrawurst wrote:
> >> > Method 1: Adding a static c'tor to every module does not 
> >> > work very long in practice (as experienced first handed) 
> >> > cause you are in "cyclic c'tor hell" very quick...
> >> 
> >> The cyclic dependency checking in druntime makes static 
> >> constructors almost unusable. It's a case of being protected 
> >> so much while trying to do something that you can't do what 
> >> you're trying to do. There really should be some way IMHO to 
> >> have something similar to @trusted where you tell the 
> >> compiler/runtime that the order does not matter for a 
> >> particular static constructor and that it should just trust 
> >> the programmer on that, but Walter rejected the idea when it 
> >> was brought up.
> >> 
> >> - Jonathan M Davis
> >
> > With LDC you can abuse the C constructor mechanism to do that. 
> > GDC does not yet expose C constructors to D code but it's on my 
> > list and it's easy to implement.
> 
> I'm not quite sure what you mean by C constructors, so I don't 
> know how that works, but unless it's in all of the compilers, I 
> don't think that it's really worth much ultimately. 

Most C compilers support some __attribute(constructor)__ feature.
In LDC this translates to something like this:

import ldc.attribute;

@attribute("constructor") extern(C) void myConstructor()
{
}

and GDC will use basically the same syntax. It's not really meant for
end users though. We can use this to implement some parts of
the druntime shared DSO handling. And it's useful for betterC programs
or embedded systems, as the implementation in the (C) runtime is very
simple. But you're right, this is probably not a good / general purpose
solution. It just wanted to point out that there's another possible
workaround ;-)

> And we _do_ 
> have workarounds already. std.stdio is an example of one such 
> module where what is essentially its static constructor is called 
> by another module in order to break the cycle. But then you lose 
> out on the special benefits of static constructors with regards 
> to initializing stuff like immutable objects, which can be a 
> problem - particularly when stuff like pure gets involved.
> 
> Honestly, I think that if we don't want it to be considered 
> borderline bad practice to use static constructors, I think that 
> we need a solution for this that allows them to function normally 
> without being concerned about circular dependencies (at least 
> when the programmer marks them as such).

I think it wouldn't be hard to implement a solution. I guess it's
mainly a political discussion :-(

An UDA which can be placed on functions with certain signatures would
be nice. And this allows having multiple static ctors per module
(Could be useful for constructors in mixins):

@constructor void myConstructor() //compiler enforces function signature
{
}

> And if the C constructor 
> mechanism that you're talking about somehow does that, then 
> great, but it needs to be standard D, or it's a pretty limited 
> solution.

If we can have a standard solution in DMD there are better ways than
relying on C constructors. The druntime has absolutely no control over
'C constructors' (they're called by the C runtime) which can lead to
problems in some corner cases. C constructors are mainly useful for low
level or embedded code. And they're useful as long as we don't have a
standard solution, as GDC/LDC can implement them without DMDs
approval ;-)


More information about the Digitalmars-d mailing list