best/proper way to declare constants ?

jfondren julian.fondren at gmail.com
Thu Aug 5 16:24:21 UTC 2021


On Thursday, 5 August 2021 at 16:06:58 UTC, someone wrote:
> So if we are talking AA-arrays at compile-time only there 
> should be nothing wrong with the following code ... right ?
...
> private enum pudtLocations = [
>    r"BUE"d : structureLocation(r"arg"d, r"Buenos Aires"d, 
> r"ART"d),
>    r"GRU"d : structureLocation(r"bra"d, r"São Paulo"d, r"BRT"d),
>    r"HHN"d : structureLocation(r"deu"d, r"Frankfurt am Main"d, 
> r"CET"d),
>    r"LHR"d : structureLocation(r"gbr"d, r"London"d, r"UTC"d),
>    r"NYC"d : structureLocation(r"usa"d, r"New York"d, r"EST"d)
>    ];

Every time you use this variable in your program, it's as if you 
retyped this definition, which can mean runtime work building the 
hash table where you use it, which can mean very surprising 
performance hits. Consider:

```d
enum aa = [1: 0];

// this is fine
unittest {
     foreach (key; aa.byKey)
         assert(aa[key] == 0);
}

// Error: associative array literal in `@nogc` function 
`enumaa.__unittest_L9_C7` may cause a GC allocation
@nogc unittest {
     foreach (key; aa.byKey)
         assert(aa[key] == 0);
}
```

It's not iteration that causes allocation, but the runtime 
building of the AA that has to happen on the spot for it to be 
iterated.

Maybe this isn't getting discussed directly enough. As rules:

1. don't use enum for AA literals

2. module-scoped AAs can be initialized in module constructors, 
like `shared static this`

3. (depending very precisely on what you want to do, you can 
break #1 with no runtime cost. For example if you never need to 
iterate over the AA or look up a compiletime-unknown key, if all 
your uses are `aa["literal key"]`, then the AA won't need to be 
constructed at runtime and this is just like putting the value of 
that key at the site)

```d
enum aa = [1: 0];

// this is fine
unittest {
     assert(aa[1] == 0);
}

// this is still fine
@nogc unittest {
     assert(aa[1] == 0);
}
```

(but that't not likely to apply to your case, especially since 
you mentioned wanting to get this data from a file at program 
start and not need literals in your program.)


More information about the Digitalmars-d-learn mailing list