On Mon, 14 Nov 2011 03:27:21 -0500, Timon Gehr <timon.g...@gmx.ch> wrote:
On 11/14/2011 01:02 AM, bearophile wrote:
Jonathan M Davis:
import std.algorithm;
void main() {
enum a = [3, 1, 2];
enum s = sort(a);
assert(equal(a, [3, 1, 2]));
assert(equal(s, [1, 2, 3]));
}
It's not a bug. Those an manifest constants. They're copy-pasted into
whatever
code you used them in. So,
enum a = [3, 1, 2];
enum s = sort(a);
is equivalent to
enum a = [3, 1, 2];
enum s = sort([3, 1, 2]);
You are right, there's no DMD bug here. Yet, it's a bit surprising to
sort in-place a "constant". I have to stop thinking of them as
constants. I don't like this design of enums...
It is the right design. Why should enum imply const or immutable? (or
inout, for that matter). They are completely orthogonal.
There is definitely some debatable practice here for wherever enum is used
on an array.
Consider that:
enum a = "hello";
foo(a);
Does not allocate heap memory, even though "hello" is a reference type.
However:
enum a = ['h', 'e', 'l', 'l', 'o'];
foo(a);
Allocates heap memory every time a is *used*. This is counter-intuitive,
one uses enum to define things using the compiler, not during runtime.
It's used to invoke CTFE, to avoid heap allocation. It's not a glorified
#define macro.
The deep issue here is not that enum is used as a manifest constant, but
rather the fact that enum can map to a *function call* rather than the
*result* of that function call.
Would you say this should be acceptable?
enum a = malloc(5);
foo(a); // calls malloc(5) and passes the result to foo.
If the [...] form is an acceptable enum, I contend that malloc should be
acceptable as well.
My view is that enum should only be acceptable on data that is immutable,
or implicitly cast to immutable, and should *never* map to an expression
that calls a function during runtime.
-Steve