Bug 2101 – CTFE: Please may I use mutable arrays at compile time?
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2008-05-12T09:25:00Z
Last change time
2015-06-09T01:19:24Z
Keywords
patch
Assigned to
nobody
Creator
caron800
Comments
Comment #0 by caron800 — 2008-05-12T09:25:06Z
The docs say I can't use non-const arrays at compile-time. But I want to, so this is an enhancement request.
The following does not compile.
int ctfeTest()
{
char[10] a; // <--- PROBLEM
return 1;
}
const int A = ctfeTest();
This does
int ctfeTest()
{
char[] a; // <--- OK
return 1;
}
but that's completely pointless. This doesn't:
int ctfeTest()
{
char[] a = new char[10]; // <--- PROBLEM
return 1;
}
Nor does this:
int ctfeTest()
{
char[] a;
a.length = 10; // <--- PROBLEM
return 1;
}
Even if we can't have dynamic arrays, what's the harm with static ones?
Comment #1 by samukha — 2008-05-12T11:41:08Z
You could use something like this (quickly hacked, dmd 1.029):
T[] newCtfeArray(T)(size_t size)
{
T[] array;
if (!size)
return array;
array ~= T.init;
if (array.length < size)
return newCtfeArray(array, size);
return array;
}
private T[] newCtfeArray(T, U = void)(T[] array, size_t size)
{
while (array.length * 2 <= size)
array ~= array;
if (array.length < size)
return array ~= newCtfeArray!(T)(size - array.length);
return array;
}
int[] test()
{
// Allocate an array of 123 ints. The memory will not be freed, sigh
auto a = newCtfeArray!(int)(123);
foreach (i, e; a)
{
a[i] = e;
}
return a;
}
void main()
{
static const a = test();
}
Comment #2 by caron800 — 2008-05-12T11:50:49Z
On 12/05/2008, [email protected] <[email protected]> wrote:
> You could use something like this (quickly hacked, dmd 1.029):
That's very clever!
But somehow, I'll be giving that a miss. What I was really after is to
be able to use new to allocate them, and to change the length by
modifying .length. That way, a good deal of existing code could
magically start working at compile time, without having to rewrite it.
Also, I don't believe there's any way to do
static if(code will be used in CTFE)
{
/* clever workarounds */
}
else
{
/* real D */
}
(Not that I'd want that, but it would at least make the clever
workarounds CTFE-only).
Comment #3 by clugdbug — 2010-01-10T14:11:14Z
Janice's first case has compiled for quite a long time now. The third case, involving 'new', is very straightforward. The final case (changing length) is doubtful whether it is a good idea. I think with implementing 'new', we can close this bug.
PATCH to allow dynamic array creation with new. Insert this code into
interpret.c, around line 2690. Also add the declaration for it in NewExp in expression.h. Also need to change the spec to remove the restriction on using 'new'.
------------
Expression *NewExp::interpret(InterState *istate)
{
#if LOG
printf("NewExp::interpret() %s\n", toChars());
#endif
if (newtype->ty == Tarray && arguments && arguments->dim == 1)
{
Expression *lenExpr = ((Expression *)(arguments->data[0]))->interpret(istate);
if (lenExpr == EXP_CANT_INTERPRET)
return EXP_CANT_INTERPRET;
return createBlockDuplicatedArrayLiteral(newtype,
newtype->defaultInitLiteral(), lenExpr->toInteger());
}
error("Cannot interpret %s at compile time", toChars());
return EXP_CANT_INTERPRET;
}