www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cannot initialize associative array.

reply dcoder <dcoder devnull.dev> writes:
Hello.  I have the following d code which fails to compile.  All 3
initializations of mywords fail.  What am I doing wrong?

thanks.


$ dmd --help
Digital Mars D Compiler v2.042
Copyright (c) 1999-2010 by Digital Mars written by Walter Bright
Documentation: http://www.digitalmars.com/d/2.0/index.html
Usage:


import std.algorithm, std.stdio, std.string;

//uint[string] mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
//auto mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
const uint[const string] mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1,
"Dog" : 1 ];

void main() {
  foreach( line; stdin.byLine()) {
    foreach( word; split(strip(line))) {
      string s = word.idup;
      if( s in mywords)
	writefln( "%s is a word I know.", s);
      else
	writefln( "%s is not a word I know.", s);
    }
  }

  return;
}
Jun 22 2010
parent reply dcoder <dcoder devenull.dev> writes:
Sorry, I forgot to put some compiler output:

For the declaration: uint[string] mywords = [ "Hello" : 1, "World" : 1, "Cat" :
1,
"Dog" : 1 ];


I get:

$ dmd test_01.d
test_01.d(3): Error: non-constant expression
["Hello":1u,"World":1u,"Cat":1u,"Dog":1u]
Jun 22 2010
next sibling parent reply Bernard Helyer <b.helyer gmail.com> writes:
On Tue, 22 Jun 2010 21:32:48 +0000, dcoder wrote:

 Sorry, I forgot to put some compiler output:
 
 For the declaration: uint[string] mywords = [ "Hello" : 1, "World" : 1,
 "Cat" : 1, "Dog" : 1 ];
 
 
 I get:
 
 $ dmd test_01.d
 test_01.d(3): Error: non-constant expression
 ["Hello":1u,"World":1u,"Cat":1u,"Dog":1u]

AAs can't be assigned to at compile time (:[). You'll have to use a static constructor or an initiliasation function to assign to one at global scope.
Jun 22 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bernard Helyer:
 AAs can't be assigned to at compile time (:[).

You can define enum ones, this works: import std.stdio; enum int[string] aa = ["foo": 10]; void main() { writeln(cast(bool)("foo" in aa)); writeln(aa["foo"]); writeln(cast(bool)("hello" in aa)); } But this code: import std.stdio; immutable int[string] aa = ["foo": 10]; void main() { writeln(cast(bool)("foo" in aa)); writeln(aa["foo"]); writeln(cast(bool)("hello" in aa)); } Raises the compilation error: test.d(2): Error: non-constant expression ["foo":10] In theory aa here is a constant expression :-) Bye, bearophile
Jun 22 2010
prev sibling parent reply dcoder <dcoder devnull.dev> writes:
 For the declaration:
 uint[string] mywords = [ "Hello" : 1, "World" : 1,
 "Cat" : 1, "Dog" : 1 ];


 I get:

 $ dmd test_01.d
 test_01.d(3): Error: non-constant expression
 ["Hello":1u,"World":1u,"Cat":1u,"Dog":1u]


 AAs can't be assigned to at compile time (:[). You'll have to use a
 static constructor or an initiliasation function to assign to one at
 global scope.

thanks Bernard. I see, so for global associative arrays, I can't do it. That's good to know, and I guess that will force me into better coding habits. Anyways, I just wish the compiler could give me a better message than what I got. :( So, I moved the initialization to inside the main function, and now it works. Great. I think we need to put this question in the FAQ. Many thanks.
Jun 22 2010
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
dcoder wrote:

 So, I moved the initialization to inside the main function, and now 

 Great.  I think we need to put this question in the FAQ.

For future reference, if it really needs to be global: uint[string] mywords; static this() { mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ]; } Ali
Jun 22 2010
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Ali Çehreli wrote:
 dcoder wrote:
 
  > So, I moved the initialization to inside the main function, and now 
 it works.
  > Great.  I think we need to put this question in the FAQ.
 
 For future reference, if it really needs to be global:
 
 uint[string] mywords;
 
 static this()
 {
     mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
 }

Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali
Jun 23 2010
next sibling parent Pelle <pelle.mansson gmail.com> writes:
On 06/23/2010 09:41 AM, Ali Çehreli wrote:
 Ali Çehreli wrote:
 dcoder wrote:

 So, I moved the initialization to inside the main function, and now

 Great. I think we need to put this question in the FAQ.

For future reference, if it really needs to be global: uint[string] mywords; static this() { mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ]; }

Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali

I say it's a bug, a literal like that should be a constant expression. Someone report it!
Jun 23 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Ali Çehreli:
 Could someone please verify whether the above is really necessary?

An initialization inside some runtime function/initializator is necessary unless the AA is an enum.
 Is it 
 actually a dmd bug that we need to use 'static this()' to initialize an 
 associative array?

According to the way D AAs are designed it's not a bug. But of course you can think of possible enhancements or changes to the design. Bye, bearophile
Jun 23 2010
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Bernard Helyer Wrote:

 On Wed, 23 Jun 2010 00:41:45 -0700, Ali Çehreli wrote:
 
 Ali Çehreli wrote:
 dcoder wrote:
 
  > So, I moved the initialization to inside the main function, and now
 it works.
  > Great.  I think we need to put this question in the FAQ.
 
 For future reference, if it really needs to be global:
 
 uint[string] mywords;
 
 static this()
 {
     mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
 }

Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali

I can't remember where exactly I read it, but there's a line in the docs specifically forbidding the use of AAs in constant expressions, so it's by design AFAIK.

http://www.digitalmars.com/d/2.0/expression.html#ArrayLiteral "Associative array literals are a comma-separated list of key:value pairs... *An AssocArrayLiteral cannot be used to statically initialize anything. *"
Jun 24 2010
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Andrej Mitrovic Wrote:

 Bernard Helyer Wrote:
 
 On Wed, 23 Jun 2010 00:41:45 -0700, Ali Çehreli wrote:
 
 Ali Çehreli wrote:
 dcoder wrote:
 
  > So, I moved the initialization to inside the main function, and now
 it works.
  > Great.  I think we need to put this question in the FAQ.
 
 For future reference, if it really needs to be global:
 
 uint[string] mywords;
 
 static this()
 {
     mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
 }

Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali

I can't remember where exactly I read it, but there's a line in the docs specifically forbidding the use of AAs in constant expressions, so it's by design AFAIK.

http://www.digitalmars.com/d/2.0/expression.html#ArrayLiteral "Associative array literals are a comma-separated list of key:value pairs... *An AssocArrayLiteral cannot be used to statically initialize anything. *"

Woops, correct link: http://www.digitalmars.com/d/2.0/expression.html#AssocArrayLiteral
Jun 24 2010
prev sibling next sibling parent Bernard Helyer <b.helyer gmail.com> writes:
On Wed, 23 Jun 2010 00:41:45 -0700, Ali Çehreli wrote:

 Ali Çehreli wrote:
 dcoder wrote:
 
  > So, I moved the initialization to inside the main function, and now
 it works.
  > Great.  I think we need to put this question in the FAQ.
 
 For future reference, if it really needs to be global:
 
 uint[string] mywords;
 
 static this()
 {
     mywords = [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
 }

Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali

I can't remember where exactly I read it, but there's a line in the docs specifically forbidding the use of AAs in constant expressions, so it's by design AFAIK.
Jun 23 2010
prev sibling parent "Rory McGuire" <rmcguire neonova.co.za> writes:
On Wed, 23 Jun 2010 00:30:40 +0200, Ali =C3=87ehreli <acehreli yahoo.com> w=
rote:

 dcoder wrote:

  > So, I moved the initialization to inside the main function, and now =

 it works.
  > Great.  I think we need to put this question in the FAQ.

 For future reference, if it really needs to be global:

 uint[string] mywords;

 static this()
 {
      mywords =3D [ "Hello" : 1, "World" : 1, "Cat" : 1, "Dog" : 1 ];
 }

 Ali

from what I have read in TDPL so far (about half way now), there is no =20 mention of this limitation. It just says that [key:value] is how you would statically initialize a AA. Does this mean that it is just a D implementation issue. To me its seems = =20 like this should be a defined part of the language. Also the compiler should really rewrite it to your above = =20 code anyway, surely? -Rory
Jun 22 2010