How can I do that in @nogc?

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Feb 25 15:37:10 PST 2015


On Wednesday, 25 February 2015 at 20:36:33 UTC, Namespace wrote:
> On Wednesday, 25 February 2015 at 20:15:10 UTC, anonymous wrote:
[...]
>> It may be possible to hack through this limitation - NOT 
>> THOUGHT-OUT, NOT TESTED, NOT RECOMMENDED:
>> ---
>> void glCheck(scope lazy int thing) @nogc;
>> pragma(mangle, glCheck.mangleof) void glCheckImpl(scope int 
>> delegate() @nogc thing) @nogc {auto x = thing();}
>> int costly() @nogc {return 42;}
>> void main() @nogc
>> {
>>    glCheck(costly());
>>    int x; glCheck(x);
>> }
>> ---
>
> That last thing works. But I have no clue why. o.O
> Anyway, thanks a lot!

I advise you to not use it. It's a hack that relies on 
implementation details of the compiler.

As for how it works:

pragma(mangle, ...) sets the mangled name of the following 
symbol. The mangled name is similar to the "fully qualified 
name", but it includes parameter types and such. So different 
overloads of a function have different mangled names, while 
sharing one fully qualified name.

Giving glCheckImpl the same mangled name as glCheck means they 
then refer to the same code despite having different signatures. 
This bypasses the type system. DON'T DO THIS.

So, whenever glCheck is called, really glCheckImpl is called, and 
the `scope lazy int` argument is interpreted as a `scope int 
delegate() @nogc` argument.

This works, because currently the compiler creates delegates for 
lazy arguments and calls those delegates when the arguments are 
accessed. So right now, `lazy int` is the same as `int 
delegate()` under the hood. But this is not guaranteed. The 
compiler is free to do this differently. It may depend on 
compiler flags, etc. SO DON'T DO THIS.


More information about the Digitalmars-d-learn mailing list