A voldemort type that wraps the value. Using it should be no different than the original pointer,
Note, it's not considered a hard failure for the first test to fail, as it's within the compiler's right to place any pointer it wants onto the stack. In the case that does happen, print a warning.
static class C { static int dtorcalls = 0; ~this() { ++dtorcalls; } } import core.memory; auto c = new C; foreach(i; 0 .. 100) GC.collect; if(C.dtorcalls != 1) { import std.stdio; writeln("WARNING: keepalive issue not detected"); } C.dtorcalls = 0; auto c2 = keepAlive(new C); foreach(i; 0 .. 100) GC.collect; assert(C.dtorcalls == 0);
Create a guaranteed-stack-allocated reference. While the thing itself cannot be copied, it should be usable just like the reference that it wraps. Because of the destructor, it is guaranteed to be put on the stack.