delegate issue

captaindet via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jun 2 12:17:54 PDT 2014


On 2014-06-02 09:57, Steven Schveighoffer wrote:
> 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

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


More information about the Digitalmars-d-learn mailing list