March 10, 2010
BCS wrote:
> I just had a crazy thought: how about allow things to explicitly state static-constructor dependencies?

My first thought is that this will be both very annoying (see the exception specification failure in Java) and will inevitably be written wrong by the user.
March 10, 2010
BCS Wrote:

> I just had a crazy thought: how about allow things to explicitly state static-constructor dependencies? By default, it would work as it does now, all constructors in all imported modules get run before any in this module but if an explicit list is given, then only that list need be run first.
> 
> My first thought was to only do this at the module level with something like this:
> 
> module foo.bar : foo.baz, foo.baz; // run first, even thought not imported
> 
> import foo.bar;
> import foo.bing; // constructors need not be run first
> 
> It might be handy to allow finer grained specification of both the ends, maybe putting the list per constructor and allowing the list to include classes for instance.

It's not a crazy idea at all, unless I am crazy also :-)

This is similar to the idea that I am now using in C++ to solve the same problem,
albeit a bit of a hack since there is no language support for it.  My idea (in C++)
is simply to have an abstract Module class which has a virtual method initialize()
that concrete Module classes implement.  Then you statically instantiate a
single instance of each Module.  At runtime, these instances are constructed
in some linker dependent order (this being a manifestation of the original problem).
But then in the constructor for Module, you list the dependencies upon other Module
classes and use this information to create a direct acyclic graph (DAG) for ultimate
invocation of the initialize() methods of all your "modules" in dependency order
(upon entering main()).

Also you can use placement operator new to construct "static objects" out of static memory (if need be), this being called in the appropriate implementation of the initialize() method for the respective "module".

Works for me but YMMV.

Cheers
Justin Johansson



March 10, 2010
On 10.03.2010 21:28, Walter Bright wrote:
>
> template Foo()
> {
> static int _a;
> static int a()
> {
> static bool _a_inited;
> if (!_a_inited)
> { _a_inited = true;
> _a = 42;
> }
> return _a;
> }
> }

Lazy initialization requires some kind of synchronization when a is shared. Static initialization does not have that drawback.
March 10, 2010
Max Samukha Wrote:

> On 10.03.2010 21:28, Walter Bright wrote:
> >
> > template Foo()
> > {
> > static int _a;
> > static int a()
> > {
> > static bool _a_inited;
> > if (!_a_inited)
> > { _a_inited = true;
> > _a = 42;
> > }
> > return _a;
> > }
> > }
> 
> Lazy initialization requires some kind of synchronization when a is shared. Static initialization does not have that drawback.

Indeed and synchronization is costly.


March 10, 2010
Max Samukha wrote:
> Lazy initialization requires some kind of synchronization when a is shared. Static initialization does not have that drawback.

That's correct (otherwise you have the double checked locking bug).

Wrapping the function body in a synchronized statement will do the trick.

(Yes, it's slower.)
March 10, 2010
On 3/10/10 16:33, Steve Teale wrote:
>>
>> The #1 show-stopper for me was lack of shared object (.so) support under
>> Linux; virtually mandated by my audience (Apache/LAMP).  (A workaround
>> like FastCGI is simply not appealing to customers.)  This topic
>> discussed many times before on this NG.
>>
>>
> I also had done a fair amount of work, and foundered on the inability to
> dynamically load anything without it being a big deal.
>
> Like you say, it has been brought up many many times. Everyone says yes,
> this is a real show-stopper, then the thread dies down and so on.
>
> Steve

What are the exact problems that people have with shared libraries on linux? I've made a few dynamic libraries on Mac OS X of which only one didn't work (I have no idea why). Among the working libraries were DWT and Tango.
March 10, 2010
On 3/10/10 19:14, Walter Bright wrote:
> Jacob Carlborg wrote:
>> I've always wonder why that is. I mean if I put an empty static
>> constructor in two modules and they import each other I get a circular
>> reference error. Usually when I use static constructors they don't
>> depend on the order of each other. Can't this be fixed if the static
>> constructors don't depend on each other?
>
>
> I don't know if there's a reasonable way of determining if they depend
> on each other, so dmd assumes they do.

I suspected that. How dangerous would it be with a compiler option that allowed the above and the programmer have to make sure that they don't depend on each other?
March 10, 2010
Jacob Carlborg Wrote:

> On 3/10/10 16:33, Steve Teale wrote:
> >>
> >> The #1 show-stopper for me was lack of shared object (.so) support under
> >> Linux; virtually mandated by my audience (Apache/LAMP).  (A workaround
> >> like FastCGI is simply not appealing to customers.)  This topic
> >> discussed many times before on this NG.
> >>
> >>
> > I also had done a fair amount of work, and foundered on the inability to dynamically load anything without it being a big deal.
> >
> > Like you say, it has been brought up many many times. Everyone says yes, this is a real show-stopper, then the thread dies down and so on.
> >
> > Steve
> 
> What are the exact problems that people have with shared libraries on linux? I've made a few dynamic libraries on Mac OS X of which only one didn't work (I have no idea why). Among the working libraries were DWT and Tango.

DMD on Linux does not support the creation of shared libraries.

March 10, 2010
Walter Bright Wrote:

> Max Samukha wrote:
> > Lazy initialization requires some kind of synchronization when a is shared. Static initialization does not have that drawback.
> 
> That's correct (otherwise you have the double checked locking bug).
> 
> Wrapping the function body in a synchronized statement will do the trick.
> 
> (Yes, it's slower.)

The issue is that we need it in a performance critical part of QtD. The library mixes in static constructors to initialise user-defined classes. This means that we can't use it when user code is in cyclic dependency. static constructors are very useful, but giving a possibility to override it's current behaviour would make them applicable to more use-cases(if you look into that bug report, another person was trying to use them exactly as we do, and faced the same problems).
March 10, 2010
Eldar Insafutdinov wrote:
> The issue is that we need it in a performance critical part of QtD.
> The library mixes in static constructors to initialise user-defined
> classes. This means that we can't use it when user code is in cyclic
> dependency. static constructors are very useful, but giving a
> possibility to override it's current behaviour would make them
> applicable to more use-cases(if you look into that bug report,
> another person was trying to use them exactly as we do, and faced the
> same problems).

I hear you. I'll try to come up with a better solution.