CTFE Allocators / @nogc
I've used D for a while and it's overall a wonderful language to work with as a hobby, but one thing that's always really bothered me is the disconnect between CTFE and allocation.
If I want dynamic memory for CTFE I have to use the GC, because the other allocators make calls to C through malloc. __ctfe is not a static variable, though, so I can't use it to swap the GC allocator and a system allocator at compile time. This means that any function I want to use for CTFE must use the GC and therefore can't be marked as @nogc (which prevents it being called from anywhere that does).
Is there any current effort to change the semantics of __ctfe or other kinds of workarounds I can try? Thank you very much in advance!
Posted Sep 10, 2018, 11:04 PM UTC
Actually allocations at compile time are all malloc. The front-end doesn't use the GC for now. All what you do in CTFE is de facto nogc. Would you have a small sample to share so that we can see more concretely what you mean ?
For a contrived example:
In CTFE you cannot use allocators (static / runtime data access) nor can you use malloc (casting rules void * -> int[] not allowed). So I have to use the GC via the new call. This works just fine and all is good, I don't have to write twice the code so I can have a CTFE version... until you add
@nogc. That__ctfecheck is not static, it's a runtime check that gets optimized out by the compiler. But because it's not static, it doesn't count as conditional compilation and using the GC violates thenogc-ness of the code even though it will never be used at runtime! You can't make it static either, because__ctfeitself cannot be read at compile time.D allows me to invalidate the
@nogcinvariant at compile time otherwise, though, as long as it's done in CTFE it has never complained before (and it rightfully shouldn't).So if I want to use test as both a CTFE and a runtime function, I have to write two functions that are almost entirely identical except one uses the allocator (which may even be the gcAllocator, which still doesn't work in CTFE) and one that uses new.
So I was wondering if there was something I was missing, if there are any plans to allow
__ctfeto be used for real conditional compilation, or if there are CTFE-compatible allocators? That way I could avoid code duplication.No you miss nothing and this problem cannot be solved with the current features of the language.