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.

Reply via email to