Associative arrays give compile error

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Tue Oct 5 05:03:21 PDT 2010


On Tue, 05 Oct 2010 12:50:44 +0100, Bob Cowdery wrote:

> On 05/10/2010 12:40, Bob Cowdery wrote:
>>  On 05/10/2010 12:13, Denis Koroskin wrote:
>>> On Tue, 05 Oct 2010 15:08:39 +0400, Bob Cowdery
>>> <bob at bobcowdery.plus.com> wrote:
>>>
>>>>  On 05/10/2010 12:04, Denis Koroskin wrote:
>>>>> On Tue, 05 Oct 2010 14:57:22 +0400, Bob Cowdery
>>>>> <bob at bobcowdery.plus.com> wrote:
>>>>>
>>>>>>  On 05/10/2010 11:45, Denis Koroskin wrote:
>>>>>>> On Tue, 05 Oct 2010 14:23:47 +0400, Bob Cowdery
>>>>>>> <bob at bobcowdery.plus.com> wrote:
>>>>>>>
>>>>>>>>  I can't seem to get any sense out of associative arrays. Even
>>>>>>>>  the
>>>>>>>> simplest definition won't compile so I must be doing something
>>>>>>>> daft.
>>>>>>>>
>>>>>>>> int[string] aa = ["hello":42];
>>>>>>>>
>>>>>>>> Error: non-constant expression ["hello":42]
>>>>>>>>
>>>>>>>> What exactly is not constant about this. The example is straight
>>>>>>>> out the
>>>>>>>> book. Using D 2.0.
>>>>>>>>
>>>>>>>> bob
>>>>>>> What exactly compiler version are you using (run dmd with no
>>>>>>> args)? Works perfectly fine here (dmd2.049).
>>>>>> It says 2.049. How odd. I've got a fair amount of code and
>>>>>> everything else compiles fine.
>>>>> Can you please post complete code snippet that fails to compile?
>>>>>
>>>>> Here is the code I used to test:
>>>>>
>>>>> module aa;
>>>>>
>>>>> import std.stdio;
>>>>>
>>>>> void main()
>>>>> {
>>>>>     int[string] aa = ["hello":42];
>>>>>     writeln(aa["hello"]);
>>>>> }
>>>>>
>>>>> # dmd -run aa.d
>>>> Ah! It's some other code below it that is not giving an error but
>>>> causing the error above. So the compiler is getting confused. What I
>>>> was actually trying to do was create an associative array with a
>>>> string as a key and a Tuple as the value. Now
>>>>
>>>> auto aa = [
>>>>     "some string": (100.0, 6100.0)
>>>> ]
>>>>
>>>> compiles but is clearly wrong and gives rise to other errors.  Does
>>>> anyone know the correct way to define this and then access the tuple.
>>> import std.stdio;
>>> import std.typecons;
>>>
>>> void main()
>>> {
>>>     auto aa = ["hello": tuple(100.0, 6100.0)]; auto result =
>>>     aa["hello"];
>>>     
>>>     writeln(result.field[0], " ", result._1); // primary and
>>> alternative way
>>> }
>> Thanks. I've established that works for me and also that the actual
>> array I'm using also works in the test program but it won't compile in
>> the real program. I've commented everything else out of the file and
>> just left...
>>
>> import std.typecons;
>>
>> auto A_RX_FILT = [
>>     "6K0": tuple(100.0, 6100.0),
>>     "2K4": tuple(300.0, 2700.0),
>>     "2K1": tuple(300.0, 2400.0),
>>     "1K0": tuple(300.0, 1300.0),
>>     "500": tuple(500.0, 1000.0),
>>     "250": tuple(600.0, 850.0),
>>     "100": tuple(700.0, 800.0)
>> ];
>>
>> I get an error on every line:
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(100,6100) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2700) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,2400) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(300,1300) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(500,1000) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(600,850) at
>> compile time|
>> Definitions\dspDefs.d|51|Error: cannot evaluate tuple(700,800) at
>> compile time|
>> ||=== Build finished: 14 errors, 0 warnings ===|
>>
>> This is a bit worrying now. I moved the array into the file that uses
>> it but I still get the same errors. Any ideas?
>>
>>
> Oh dear, this is getting worse and worse. I've still got problems with a
> simple definition. If I take out the one with the tuple and leave in
> this one:
> 
> enum E_MODE
> {
>   LSB,                //  0
>   USB,                //  1
>   DSB,                //  2
>   CWL,                //  3
>   CWU,                //  4
>   FMN,                //  5
>   AM,                //  6
>   DIGU,                //  7
>   SPEC,                //  8
>   DIGL,                //  9
>   SAM,                // 10
>   DRM                // 11
> }
> // Associative array for translation
> auto A_MODE = [
>     "LSB": E_MODE.LSB,
>     "USB": E_MODE.USB,
>     "DSB": E_MODE.DSB,
>     "CWL": E_MODE.CWL,
>     "CWU": E_MODE.CWU,
>     "FMN": E_MODE.FMN,
>     "AM": E_MODE.AM,
>     "DIGU": E_MODE.DIGU,
>     "SPEC": E_MODE.SPEC,
>     "DIGL": E_MODE.DIGL,
>     "SAM": E_MODE.SAM,
>     "DRM": E_MODE.DRM
> ];
> 
> I get:
> Definitions\dspDefs.d|25|Error: non-constant expression
> ["LSB":cast(E_MODE)0,"USB":cast(E_MODE)1,"DSB":cast(E_MODE)2,"CWL":cast
(E_MODE)3,"CWU":cast(E_MODE)4,"FMN":cast(E_MODE)5,"AM":cast(E_MODE)
6,"DIGU":cast(E_MODE)7,"SPEC":cast(E_MODE)8,"DIGL":cast(E_MODE)
9,"SAM":cast(E_MODE)10,"DRM":cast(E_MODE)11]|
> ||=== Build finished: 1 errors, 0 warnings ===|
> 
> Something is seriously broken here.

No, nothing is broken. :)

The problem is that you are trying to create an associative array at 
compile time, which isn't possible.  This works:

  void main()
  {
      auto foo = [ "Hello" : "World" ];  // Array created at run time
      writeln(foo);
  }

This doesn't work:


  auto foo = [ "Hello" : "World" ]; // Cannot create AA at compile time

  void main()
  {
      writeln(foo);
  }

To create a module-level AA which is initialised on program start, use a 
module constructor:

  string[string] foo;

  static this()
  {
     foo = [ "Hello" : "World" ];
  }

  void main()
  {
      writeln(foo);
  }

In your case, this would mean:

Tuple!(double, double)[string] A_RX_FILT;

static this()
{
  A_RX_FILT = [
    "6K0": tuple(100.0, 6100.0),
    "2K4": tuple(300.0, 2700.0),
    "2K1": tuple(300.0, 2400.0),
    "1K0": tuple(300.0, 1300.0),
    "500": tuple(500.0, 1000.0),
    "250": tuple(600.0, 850.0),
    "100": tuple(700.0, 800.0)
  ];
}

-Lars


More information about the Digitalmars-d-learn mailing list