Thread overview
How to declare static compile-time assoc array inside struct?
Aug 13, 2018
Andrey
Aug 13, 2018
rikki cattermole
Aug 13, 2018
Andrey
Aug 14, 2018
Jonathan M Davis
Aug 13, 2018
Andrey
Aug 13, 2018
Timoses
Aug 13, 2018
Seb
Aug 17, 2018
Jonathan M Davis
August 13, 2018
Hello,
I need to declare a static compile-time assoc array inside struct:
    struct Test
    {
        enum Type : ubyte
        {
            One,
            Two,
            Three
        }

        static immutable string[Type] DESCRIPTION = [Type.One: "One!", Type.Two: "It's Two...", Type.Three: "And... Three!"];
    }

I have an error: "non-constant expression". What should I do?

I want to declare it and init at compile-time (to reduce run-time overhead). After that it will be used in run-time expressions and in compile-time expressions.

Regards, Andrey.
August 13, 2018
On 13/08/2018 11:38 PM, Andrey wrote:
> Hello,
> I need to declare a static compile-time assoc array inside struct:
>      struct Test
>      {
>          enum Type : ubyte
>          {
>              One,
>              Two,
>              Three
>          }
> 
>          static immutable string[Type] DESCRIPTION = [Type.One: "One!", Type.Two: "It's Two...", Type.Three: "And... Three!"];
>      }
> 
> I have an error: "non-constant expression". What should I do?
> 
> I want to declare it and init at compile-time (to reduce run-time overhead). After that it will be used in run-time expressions and in compile-time expressions.
> 
> Regards, Andrey.

Unsupported. AA's don't go between CT and RT. You must use a module constructor to initialize it.
August 13, 2018
On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
> Unsupported. AA's don't go between CT and RT. You must use a module constructor to initialize it.

Will be supported in future?
August 13, 2018
On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
> You must use a module constructor to initialize it.

Tried this:
static this()
{
    Test.DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"];
}

struct Test
{
    // ...
}

I have an error: cannot modify immutable expression DESCRIPTION
August 13, 2018
On Monday, 13 August 2018 at 13:21:45 UTC, Andrey wrote:
> On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
>> You must use a module constructor to initialize it.
>
> Tried this:
> static this()
> {
>     Test.DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"];
> }
>
> struct Test
> {
>     // ...
> }
>
> I have an error: cannot modify immutable expression DESCRIPTION

I suppose something along these lines was meant:

    immutable string[Test.Type] DESCRIPTION;

    shared static this()
    {
        DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"];
    }

    struct Test
    {
        enum Type { One, Two, Three };
    }

See also:
https://forum.dlang.org/post/p941qc$43q$1@digitalmars.com
August 13, 2018
On Monday, 13 August 2018 at 13:21:45 UTC, Andrey wrote:
> On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
>> You must use a module constructor to initialize it.
>
> Tried this:
> static this()
> {
>     Test.DESCRIPTION = [Test.Type.One: "One!", Test.Type.Two: "It's Two...", Test.Type.Three: "And... Three!"];
> }
>
> struct Test
> {
>     // ...
> }
>
> I have an error: cannot modify immutable expression DESCRIPTION

What is your other code?

It can work, e.g.:

https://run.dlang.io/is/kAC4pl
August 13, 2018
On Monday, August 13, 2018 6:14:56 AM MDT Andrey via Digitalmars-d-learn wrote:
> On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
> > Unsupported. AA's don't go between CT and RT. You must use a module constructor to initialize it.
>
> Will be supported in future?

Maybe, but don't plan on it. Stefan Koch is working on a major rewrite for CTFE (which he calls newCTFE), but it's going to be a while before that's done (as in, it won't be done this year and has no definitive timeframe for completion). I don't know if he has plans to improve AA support with newCTFE (I think that he's mostly focused on getting to the point that it supports everything that the current CTFE supports but way more efficiently), but either way, I very much doubt that anyone is going to rework the current CTFE implementation to support having AAs transfer from compile-time to runtime. So, while you might get that ability at some point in the future, for now (and possibly permanently), you will need to proceed without that ability.

- Jonathan M Davis



August 17, 2018
On 8/13/18 9:21 AM, Andrey wrote:
> On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
>> You must use a module constructor to initialize it.
> 
> Tried this:
> static this()

`shared static this()`

normal static this runs on every thread creation, and so cannot modify immutable data.

-Steve
August 17, 2018
On Friday, August 17, 2018 9:59:18 AM MDT Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 8/13/18 9:21 AM, Andrey wrote:
> > On Monday, 13 August 2018 at 11:53:06 UTC, rikki cattermole wrote:
> >> You must use a module constructor to initialize it.
> >
> > Tried this:
> > static this()
>
> `shared static this()`
>
> normal static this runs on every thread creation, and so cannot modify immutable data.

Well, it's not _supposed_ to be able to modify immutable data. It's a long-standing bug that the compiler allows you to initialize immutable variables in non-shared, static constructors, and if you do it, it's going to reinitialize it in each thread, which is definitely not good, but for whatever reason hasn't managed to be enough of a priority to get fixed.

https://issues.dlang.org/show_bug.cgi?id=4923

So, unfortunately, it's currently up to the programmer to get it right, and they won't get an error when they screw it up.

- Jonathan M Davis