enum str = "abc"; vs string str = "abc";

Mathias Lang pro.mathias.lang at gmail.com
Thu Jan 17 05:00:58 UTC 2019


On Wednesday, 16 January 2019 at 18:21:29 UTC, Victor Porton 
wrote:
> What is more space efficient:
>
> enum str = "safjkdfjksdlfkdsj";
>
> or
>
> string str = "safjkdfjksdlfkdsj";
>
> ?
>
> with the first code fragment, won't the string be re-created 
> and re-inserted into the object file one time whenever str is 
> used, rather than once?
>
> What of the two you would recommend?

I've seen people using mostly `enum` over `(static) immutable`, 
but...

When we ported our code from D1 to D2 in Sociomantic, we created 
a small fixup tool 
(https://github.com/sociomantic-tsunami/d1to2fix) and one of its 
job was to convert D1-style manifest constant (`const X = 
initializer;`) into "D2 style" (`enum X = initializer;`). And 
allocations started to show up where they would not before. After 
we got a rather complete and insightful explanation of the 
difference between `enum` and `static immutable` by Don Clugston, 
we switched to `static immutable` (almost) everywhere, and that 
was definitely a win.

You can see `enum` as a `#define`. It will get "copy-pasted" 
everywhere, and thus, it's a rvalue (you can't take the address 
of an enum). On the other hand, `static immutable` are actual 
variable that will live in the binary. They are a symbol you can 
take the address of. They behave exactly like you would want a 
manifest constant to behave. There is only one corner case I know 
of where enum is more practical, it's the following code:

```D
static immutable INITIALIZER = [1, 2, 3, 4]; // Does not work 
because it tries to do immutable -> mutable
enum INITIALIZER = [1, 2, 3, 4]; // Works because every time it 
is used, it allocates a new array
void foo (int[] value = INITIALIZER) { ... }
```

That being said, the DMD frontend is clever enough to avoid 
pointless allocations in the most obvious cases. So for example 
an array literal indexed by a compile-time known index will not 
allocate (`enum ARR = [0, 1, 2]; int i = ARR[0];`). However, if 
the index is not known at compile time, it will allocate every 
time with `enum`, never with `static immutable`.


TL;DR: Use `static immutable` by default, `enum` if you want a 
`#define`.


More information about the Digitalmars-d mailing list