Just don't do it.
Use const
or immutable
.
If you want to force CTFE, then use static const
or static immutable
.
First, using an enumerable as a constant is quite strange in itself.
Second, look at this:
pragma(inline, false)
void sideEffect(const int[] arr) @nogc {
import core.volatile;
volatileLoad(cast(uint*) arr.ptr);
}
int[] genArray(size_t length) {
auto result = new int[length];
foreach(i, ref e; result) e = cast(int) i;
return result;
}
void useEnum() {
enum f1 = genArray(3);
sideEffect(f1);
sideEffect(f1);
}
void useConst() {
static const f1 = genArray(3);
sideEffect(f1);
sideEffect(f1);
}
Assembler output (ldc2 -O3):
void example.useEnum():
push r14
push rbx
push rax
mov r14, qword ptr [rip + TypeInfo_xAi.__init@GOTPCREL]
mov esi, 3
mov rdi, r14
call _d_newarrayU@PLT
movabs rbx, 4294967296
mov qword ptr [rdx], rbx
mov dword ptr [rdx + 8], 2
mov edi, 3
mov rsi, rdx
call @nogc void example.sideEffect(const(int[]))@PLT
mov esi, 3
mov rdi, r14
call _d_newarrayU@PLT
mov qword ptr [rdx], rbx
mov dword ptr [rdx + 8], 2
mov edi, 3
mov rsi, rdx
add rsp, 8
pop rbx
pop r14
jmp @nogc void example.sideEffect(const(int[]))@PLT
void example.useConst():
push rbx
lea rbx, [rip + .dynarrayStorage]
mov edi, 3
mov rsi, rbx
call @nogc void example.sideEffect(const(int[]))@PLT
mov edi, 3
mov rsi, rbx
pop rbx
jmp @nogc void example.sideEffect(const(int[]))@PLT
.dynarrayStorage:
.long 0
.long 1
.long 2
We should ban it forever.
enum a = 10;
const a = 10;