[dmd-internals] Determining whether an expression can be transformed into a constant initializer

David Nadlinger code at klickverbot.at
Tue Oct 15 08:48:59 PDT 2013


As highlighted during a recent off-list discussion, the following D
program should not allocate any GC memory, and indeed doesn't with LDC
(as the array literal is only accessible via const/immutable
references, it can be emitted as constant data):

---
extern(C) int printf(const char*, ...);
void main() {
    immutable int[] z = [1, 2, 3];
    printf("%d\n", z[2]);
}
---

In contrast, the following function obviously needs to allocate, as
the value can't be expressed as a constant:
---
immutable(int)[] foo(int a) { return [ a ]; }
---

The question now is how to best determine whether a given
ArrayLiteralExp is actually constant (i.e. can be emitted to the data
segment). LDC currently uses Expression::isConst in its
proof-of-concept implementation, but this is way too conservative, as
it is used during frontend constant folding and e.g. doesn't regard
any StructLiteralExps as constant.

The best idea I could come up with so far is to call ctfeInterpret()
on the array literal elements with errors gagged and see if it works
out, but that's not a particularly elegant solution.

Any other ideas on how to implement this? The requirements are the
same as for global variable initializers, but there, the
ctfeInterpret() approach can be used naturally (without errors
gagged).

David


More information about the dmd-internals mailing list