best/proper way to declare constants ?

someone someone at somewhere.com
Thu Aug 5 16:53:38 UTC 2021


On Thursday, 5 August 2021 at 16:24:21 UTC, jfondren wrote:
> 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.)

Yes. Of course I remember the post you mention in which I stated 
the possibility of loading data from a file. And somehow this 
post in which I am asking for advice to finally nail-down const 
usage in D went back to the problem I encountered with AA at 
compile-time (byKeyValue) when I did not clearly understand the 
differences of using arrays/AA at compile-time vs run-time.

My conclusion of said post was that I have to find an alternative 
to AA at compile-time, and then, in this post, when I saw the 
comment:

"AA's are already available at compile-time" [H S Teoth]

and then the related:

"We really need to fix this" [H S Teoth]

I thought that probably there was nothing wrong with my code to 
begin with and thus I somehow re-asked the original question 
about AA at compile-time.

As you pointed me, using them the way I am using them, leads to 
usable code at the cost of horrible-performance compilation 
because of the copy/paste/build-hash-table-once-again the 
compiler has to do *each* time I reference them.

I already assumed that loading the data from file is a goner.

So this leaves me with two choices:

- keep the code as it is incurring higher-than expected 
compilation-time: this is solely used in a module to build 
classes, I guess pretty minimal usage, but I don't know where 
this app will eventually go so better get it right to begin with

- find a better alternative

Thanks for your advice jfondren :) !


More information about the Digitalmars-d-learn mailing list