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

Reply via email to