What's the difference between
enum i = 2;
enum s = "Hello";
and
immutable i = 2;
immutable s = "Hello";
in D 2.0?
An enum
is a user-defined type, not a variable. enum e = 2;
is a
short-hand for something like this enum : int { e = 2 }
(i.e. an anonymous
enum with one member e
), see the documentation.
By definition, all members of an anonymous enum are placed into the current
scope. So, e
is a type member placed into the current scope, where it behaves
like a literal.
immutable i = 2;
on the other hand actually creates a variable i
of type int.
This difference has a couple of consequences:
enum e
will have no memory location and no address (is no lvalue), since
neither a type nor its members have an address. I.e. you cannot do something
like auto ptr = &e;
(just like you cannot do auto ptr = &2;
). immutable
i
on the other hand is a normal variable (just immutable).e
with 2
. For i
it
usually has to create a memory location (although an optimizing compiler
might be able to avoid this sometimes). For this reason, the workload during
compilation for an enum
might be expected to be somewhat lower, and the
binary somewhat smaller.enum uint[2] E = [0, 1];
and
immutable uint[2] I = [0, 1];
the access to the enum
, e.g. E[0]
, can
be orders of magnitude slower than for the immutable
array, e.g. I[0]
,
especially as the arrays E
and I
get bigger. This is so because for an
immutable
array, it is just a normal array lookup to, say, a global
variable. For the enum
however it looks like the array gets created every
time before it gets used, e.g. inside a function for a global enum
(don't
ask me, why, but the compiler really seems to simply replace the appearance
with the value in this case, too). I have never tried but would guess that
the same applies to enum
strings and other non-trivial types.To sum up: when I use compile-time constants, I usually take enum
unless
those constants are arrays or I need a memory location for some other reason.