On 2014-06-02 09:57, Steven Schveighoffer wrote:
On Mon, 02 Jun 2014 10:37:07 -0400, captaindet <2k...@gmx.net> wrote:
On 2014-06-02 08:03, MrSmith wrote:
On Monday, 2 June 2014 at 06:56:54 UTC, captaindet wrote:
hi,
i stumbled upon something weird - it looks like a bug to me but
maybe it is a "feature" that is unclear to me.
so i know i can declare function and delegate pointers at module level.
for function pointers, i can initialize with a lambda.
BUT for delegates i get an error - see below
i found out that using module static this(){...} provides a workaround, but why
is this necessary?
also, if there is a good reason after all then the error message should make
more sense.
/det
ps: i know there is a shorthand syntax for this.
----
module demo;
int function(int) fn = function int(int){ return 42; };
// ok
int delegate(int) dg = delegate int(int){ return 666; };
// demo.d(6): Error: non-constant nested delegate literal expression
__dgliteral6
void main(){}
You can't assign a delegate at compile time now.
But you can do this in static constructor like this:
int delegate(int) dg;
static this()
{
dg = delegate int(int){ return 666; };
}
i knew about the static constructor, mentioned it in my OP ;)
tried it in my project proper and got run-time cycle detected between modules
ctors/dtors :(
something new to figure out now.
FYI, the module ctor/dtor cycles thing is an interesting problem.
When D decides to call module ctors or dtors, it wants to initialize
them in an order where two initializations don't depend on one
another. For instance:
module a;
import b;
int x;
static this() { x = b.x;}
module b;
import a;
int x;
static this() { x = a.x;}
But of course, D does not know what exactly is done in module a, and
module b. It could be:
module a;
import b;
int x;
static this() { x = b.x; }
module b;
import a;
int x;
static this() { x = 15;}
Which could be perfectly legal, as long as module b is initialized
before module a.
But D doesn't have the information to sort this out. So at the
moment, it has to assume the first situation, and reject the code.
And it can only detect this at runtime, since we have no way to tell
the linker to refuse to link this code.
The typical solution is to put your static ctors into another module,
which nothing will import (and therefore cannot be part of a cycle).
A module with no static ctors/dtors will not be flagged as causing a
problem.
-Steve
thanks a lot, steve! turned out - not surprisingly - that i would run into the
ctor/dtor cycle issue whenever the user code module had a static constructor
(even if not due to the delegate workaround mixin). i was able to refactor my
package and after 'outsourcing' of the static constructor there, i can now use
the mixed in static constructors in the user module to initialize the delegate
with a default. not pretty, but it works!
/det