www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Bug in usage of associative array: dynamic array with string as a key

reply Cecil Ward <cecil cecilward.com> writes:
I have code roughly like the following:

    dstring str = "name"d;
    uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;

struct Decls
    {
    uint[ dstring]   ordinals;
    }

//and
    Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out? I took this from the example 
given in the language reference under arrays, testing for 
membership (or similar, I forget the subssection title).

 From good old printfs it seems to be the case that the array is 
being populated (elsewhere) with the expected correct values. 
Taking out the if doesn’t seem to help either. I don’t have a way 
of examining the contents of the dynamic array directly to check 
that they are actually being stored as expected, other than 
seeing that that line of code is indeed being executed with the 
expected values of str going in. Note that I’m using 32-bit 
dstrings everywhere, not strings of bytes.
Jun 30 2023
next sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:
 I have code roughly like the following:

    dstring str = "name"d;
    uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
 Decls.ordinals[ str ]  :  -1;

 struct Decls
    {
    uint[ dstring]   ordinals;
    }

 //and
    Decls.ordinals[ str ] = ordinal_counter++;

 The problem is that it always returns ordinal== -1 from the 
 expression. Can you sort me out?
Impossible to tell without a complete repro, I'm afraid. The expression, at least, looks correct at first glance. Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.
Jun 30 2023
parent reply Cecil Ward <cecil cecilward.com> writes:
On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:
 On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:
 I have code roughly like the following:

    dstring str = "name"d;
    uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
 Decls.ordinals[ str ]  :  -1;

 struct Decls
    {
    uint[ dstring]   ordinals;
    }

 //and
    Decls.ordinals[ str ] = ordinal_counter++;

 The problem is that it always returns ordinal== -1 from the 
 expression. Can you sort me out?
Impossible to tell without a complete repro, I'm afraid. The expression, at least, looks correct at first glance. Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.
Is the second argument an ‘else’ then, my friend?
Jun 30 2023
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/30/23 13:16, Cecil Ward wrote:
 On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:
 Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.
Is the second argument an ‘else’ then, my friend?
Yes, .get and friends appear in this table: https://dlang.org/spec/hash-map.html#properties Ali
Jun 30 2023
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/30/23 12:05, Cecil Ward wrote:
 I have code roughly like the following:

     dstring str = "name"d;
Aside: One almost never needs dstring.
     uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
 Decls.ordinals[ str ]  :  -1;

 struct Decls
     {
     uint[ dstring]   ordinals;
Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals does not compile.
     }

 //and
     Decls.ordinals[ str ] = ordinal_counter++;
Are you doing that *after* you initialize 'ordinal' as you show here? :) Ali
Jun 30 2023
parent Cecil Ward <cecil cecilward.com> writes:
On Friday, 30 June 2023 at 20:12:08 UTC, Ali Çehreli wrote:
 On 6/30/23 12:05, Cecil Ward wrote:
 I have code roughly like the following:

     dstring str = "name"d;
Aside: One almost never needs dstring.
     uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
 Decls.ordinals[ str ]  :  -1;

 struct Decls
     {
     uint[ dstring]   ordinals;
Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals does not compile.
     }

 //and
     Decls.ordinals[ str ] = ordinal_counter++;
Are you doing that *after* you initialize 'ordinal' as you show here? :) Ali
Hi Ali, ‘ordinal’ is a static initialised explicitly with zero.
Jun 30 2023
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Jun 30, 2023 at 07:05:23PM +0000, Cecil Ward via Digitalmars-d-learn
wrote:
[...]

It would help if you could post the complete code that reproduces the
problem. Or, if you do not wish to reveal your code, reduce it to a
minimal case that still exhibits the same problem, so that we can see it
for ourselves.  The snippets you provided do not provide enough
information to identify the problem.


T

-- 
What's the difference between a 4D tube and an overweight Dutchman?  One
is a hollow spherinder, and the other is a spherical Hollander.
Jun 30 2023
parent reply Cecil Ward <cecil cecilward.com> writes:
On Friday, 30 June 2023 at 21:25:23 UTC, H. S. Teoh wrote:
 On Fri, Jun 30, 2023 at 07:05:23PM +0000, Cecil Ward via 
 Digitalmars-d-learn wrote: [...]

 It would help if you could post the complete code that 
 reproduces the problem. Or, if you do not wish to reveal your 
 code, reduce it to a minimal case that still exhibits the same 
 problem, so that we can see it for ourselves.  The snippets you 
 provided do not provide enough information to identify the 
 problem.


 T
I would indeed need to cut it down massively, as the original code is ~2k lines. Mind you, I will just end up with the example at https://dlang.org/spec/hash-map.html#testing_membership in the language docs, under associative arrays - 13.3 testing membership. Would anyone else care to try that example out as that might be quicker? That’s because as all I did was copy that basically, with the only substantive change being deleting the variable p, but I’m still testing whether or not I get a null pointer. I thought I had checked that the insertions were all as expected, so I’ll go and recheck that next.
Jun 30 2023
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/30/23 17:42, Cecil Ward wrote:

 https://dlang.org/spec/hash-map.html#testing_membership in the language
 docs, under associative arrays - 13.3 testing membership. Would anyone
 else care to try that example out as that might be quicker?
I tried it by 1) Putting all the code inside a 'void main()' function 2) Pasting the code from the top of that page and it works: void main() { int[string] aa; // Associative array of ints that are // indexed by string keys. // The KeyType is string. aa["hello"] = 3; // set value associated with key "hello" to 3 int value = aa["hello"]; // lookup value from a key assert(value == 3); int* p; p = "hello" in aa; if (p !is null) { *p = 4; // update value associated with key assert(aa["hello"] == 4); } }
 the only substantive
 change being deleting the variable p
Do you mean this: aa.remove("hello"); That works too. D's associative arrays have a few quirks but they work just fine. They are not buggy as it may be inferred from some of the posts here. Ali
Jun 30 2023
prev sibling next sibling parent mw <mw g.c> writes:
https://forum.dlang.org/thread/duetqujuoceancqtjlar forum.dlang.org

Try HashMap see if it is still a problem.

If no, then it's another example of the built in AA problem.
Jun 30 2023
prev sibling parent Cecil Ward <cecil cecilward.com> writes:
On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:
 I have code roughly like the following:

    dstring str = "name"d;
    uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
 Decls.ordinals[ str ]  :  -1;

 struct Decls
    {
    uint[ dstring]   ordinals;
    }

 //and
    Decls.ordinals[ str ] = ordinal_counter++;

 The problem is that it always returns ordinal== -1 from the 
 expression. Can you sort me out? I took this from the example 
 given in the language reference under arrays, testing for 
 membership (or similar, I forget the subssection title).

 From good old printfs it seems to be the case that the array is 
 being populated (elsewhere) with the expected correct values. 
 Taking out the if doesn’t seem to help either. I don’t have a 
 way of examining the contents of the dynamic array directly to 
 check that they are actually being stored as expected, other 
 than seeing that that line of code is indeed being executed 
 with the expected values of str going in. Note that I’m using 
 32-bit dstrings everywhere, not strings of bytes.
Fool that I am. I did those good old printfs a while back, and now I recheck them I see that something has become broken and it seems that the insertions are not happening now. So thankyou for your kindness and I’ll post again if that doesn’t solve the non-issue.
Jun 30 2023