delegate issue

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 2 07:57:01 PDT 2014


On Mon, 02 Jun 2014 10:37:07 -0400, captaindet <2krnk at 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


More information about the Digitalmars-d-learn mailing list