Thread overview
Weird hash (associative array) init behaviour?
May 12, 2004
Helmut Leitner
May 12, 2004
Ivan Senji
May 12, 2004
Helmut Leitner
May 12, 2004
Ben Hinkle
May 12, 2004
C
May 12, 2004
Andrew Edwards
May 13, 2004
C
May 13, 2004
Ben Hinkle
May 13, 2004
J Anderson
May 12, 2004
The following small program

  alias char[] Str;
  alias int [char []] Bag;

  Bag bag1;
  Bag bag2;

  void BagAddElem(Bag bag,Str key)
  {
    int count=bag[key];
    if(count>0) {
      bag[key]=count+1;
    } else {
      bag[key.dup]=1;
    }
  }

  int main()
  {
    int count=bag2["TEST"];

    BagAddElem(bag1,"TEST");
    BagAddElem(bag2,"TEST");

    printf("bag1.keys.length=%d\n",bag1.keys.length);
    printf("bag2.keys.length=%d\n",bag2.keys.length);

    return 0;
 }

creates the output:

  bag1.keys.length=0
  bag2.keys.length=1

Expected is:

  bag1.keys.length=1
  bag2.keys.length=1

The only difference is the first access to the two bags.
  (1) bag1 is first questioned (while still empty)
  (2) bag2 gets an element added frist

(1) seems to disable bag1 for all further accesses (this hit me
in a real world program, where 193.000 adds didn't get into the bag).

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
May 12, 2004
"Helmut Leitner" <leitner@hls.via.at> wrote in message news:40A23CCD.F78AD327@hls.via.at...
> The following small program
>
>   alias char[] Str;
>   alias int [char []] Bag;
>
>   Bag bag1;
>   Bag bag2;
>
>   void BagAddElem(Bag bag,Str key)
>   {
>     int count=bag[key];
>     if(count>0) {
>       bag[key]=count+1;
>     } else {
>       bag[key.dup]=1;
>     }
>   }

Shouldn't you pass Bag as inout Bag if you are trying to change it inside the function? That is the reason that bag1 and bag2 size doesn't change.

>   int main()
>   {
>     int count=bag2["TEST"];
>
>     BagAddElem(bag1,"TEST");
>     BagAddElem(bag2,"TEST");
>
>     printf("bag1.keys.length=%d\n",bag1.keys.length);
>     printf("bag2.keys.length=%d\n",bag2.keys.length);
>
>     return 0;
>  }
>
> creates the output:
>
>   bag1.keys.length=0
>   bag2.keys.length=1
>
> Expected is:
>
>   bag1.keys.length=1
>   bag2.keys.length=1
>
> The only difference is the first access to the two bags.
>   (1) bag1 is first questioned (while still empty)
>   (2) bag2 gets an element added frist
>
> (1) seems to disable bag1 for all further accesses (this hit me
> in a real world program, where 193.000 adds didn't get into the bag).
>
> --
> Helmut Leitner    leitner@hls.via.at
> Graz, Austria   www.hls-software.com


May 12, 2004

Ivan Senji wrote:
> 
> "Helmut Leitner" <leitner@hls.via.at> wrote in message news:40A23CCD.F78AD327@hls.via.at...
> > The following small program
> >
> >   alias char[] Str;
> >   alias int [char []] Bag;
> >
> >   Bag bag1;
> >   Bag bag2;
> >
> >   void BagAddElem(Bag bag,Str key)
> >   {
> >     int count=bag[key];
> >     if(count>0) {
> >       bag[key]=count+1;
> >     } else {
> >       bag[key.dup]=1;
> >     }
> >   }
> 
> Shouldn't you pass Bag as inout Bag if you are trying to change it inside the function? That is the reason that bag1 and bag2 size doesn't change.

Maybe I should use inout (I thought of it as an object pointer, not as an array reference), but bag2 *does* change through the same interface. The only difference is the initial query of bag2.

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
May 12, 2004
"Helmut Leitner" <helmut.leitner@wikiservice.at> wrote in message news:40A266E1.76885A65@wikiservice.at...
>
>
> Ivan Senji wrote:
> >
> > "Helmut Leitner" <leitner@hls.via.at> wrote in message news:40A23CCD.F78AD327@hls.via.at...
> > > The following small program
> > >
> > >   alias char[] Str;
> > >   alias int [char []] Bag;
> > >
> > >   Bag bag1;
> > >   Bag bag2;
> > >
> > >   void BagAddElem(Bag bag,Str key)
> > >   {
> > >     int count=bag[key];
> > >     if(count>0) {
> > >       bag[key]=count+1;
> > >     } else {
> > >       bag[key.dup]=1;
> > >     }
> > >   }
> >
> > Shouldn't you pass Bag as inout Bag if you are trying to change it inside the function? That is the reason that bag1 and bag2 size doesn't change.
>
> Maybe I should use inout (I thought of it as an object pointer, not as an array reference), but bag2 *does* change through the same interface. The only difference is the initial query of bag2.

The statement
  int count=bag2["TEST"];
will add TEST to bag2 with initialized value (which is 0 for int) if it
isn't already in there.
An associative array has the same length field and data pointer fields as a
dynamic array. So when you pass it to a function if the function either
1) calls rehash, which would reallocate the data pointer or
2) adds the first element to an unused array (the case you have here)
then you should make the variable "inout" so that those changes are
reflected in the original array - assuming that is what you want.

> -- 
> Helmut Leitner    leitner@hls.via.at
> Graz, Austria   www.hls-software.com


May 12, 2004
Yes, use 'in' to determine if a key exists, and isnt 'inout' the default anyway ?

On Wed, 12 May 2004 14:35:01 -0400, Ben Hinkle <bhinkle@mathworks.com> wrote:

>
> "Helmut Leitner" <helmut.leitner@wikiservice.at> wrote in message
> news:40A266E1.76885A65@wikiservice.at...
>>
>>
>> Ivan Senji wrote:
>> >
>> > "Helmut Leitner" <leitner@hls.via.at> wrote in message
>> > news:40A23CCD.F78AD327@hls.via.at...
>> > > The following small program
>> > >
>> > >   alias char[] Str;
>> > >   alias int [char []] Bag;
>> > >
>> > >   Bag bag1;
>> > >   Bag bag2;
>> > >
>> > >   void BagAddElem(Bag bag,Str key)
>> > >   {
>> > >     int count=bag[key];
>> > >     if(count>0) {
>> > >       bag[key]=count+1;
>> > >     } else {
>> > >       bag[key.dup]=1;
>> > >     }
>> > >   }
>> >
>> > Shouldn't you pass Bag as inout Bag if you are trying to
>> > change it inside the function? That is the reason that bag1
>> > and bag2 size doesn't change.
>>
>> Maybe I should use inout (I thought of it as an object pointer,
>> not as an array reference), but bag2 *does* change through the
>> same interface. The only difference is the initial query of bag2.
>
> The statement
>   int count=bag2["TEST"];
> will add TEST to bag2 with initialized value (which is 0 for int) if it
> isn't already in there.
> An associative array has the same length field and data pointer fields as a
> dynamic array. So when you pass it to a function if the function either
> 1) calls rehash, which would reallocate the data pointer or
> 2) adds the first element to an unused array (the case you have here)
> then you should make the variable "inout" so that those changes are
> reflected in the original array - assuming that is what you want.
>
>> --
>> Helmut Leitner    leitner@hls.via.at
>> Graz, Austria   www.hls-software.com
>
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 12, 2004
C wrote:
> Yes, use 'in' to determine if a key exists, and isnt 'inout' the default anyway ?

No the default is 'in'!

> 
> On Wed, 12 May 2004 14:35:01 -0400, Ben Hinkle <bhinkle@mathworks.com> wrote:
> 
>>
>> "Helmut Leitner" <helmut.leitner@wikiservice.at> wrote in message
>> news:40A266E1.76885A65@wikiservice.at...
>>
>>>
>>>
>>> Ivan Senji wrote:
>>> >
>>> > "Helmut Leitner" <leitner@hls.via.at> wrote in message
>>> > news:40A23CCD.F78AD327@hls.via.at...
>>> > > The following small program
>>> > >
>>> > >   alias char[] Str;
>>> > >   alias int [char []] Bag;
>>> > >
>>> > >   Bag bag1;
>>> > >   Bag bag2;
>>> > >
>>> > >   void BagAddElem(Bag bag,Str key)
>>> > >   {
>>> > >     int count=bag[key];
>>> > >     if(count>0) {
>>> > >       bag[key]=count+1;
>>> > >     } else {
>>> > >       bag[key.dup]=1;
>>> > >     }
>>> > >   }
>>> >
>>> > Shouldn't you pass Bag as inout Bag if you are trying to
>>> > change it inside the function? That is the reason that bag1
>>> > and bag2 size doesn't change.
>>>
>>> Maybe I should use inout (I thought of it as an object pointer,
>>> not as an array reference), but bag2 *does* change through the
>>> same interface. The only difference is the initial query of bag2.
>>
>>
>> The statement
>>   int count=bag2["TEST"];
>> will add TEST to bag2 with initialized value (which is 0 for int) if it
>> isn't already in there.
>> An associative array has the same length field and data pointer fields as a
>> dynamic array. So when you pass it to a function if the function either
>> 1) calls rehash, which would reallocate the data pointer or
>> 2) adds the first element to an unused array (the case you have here)
>> then you should make the variable "inout" so that those changes are
>> reflected in the original array - assuming that is what you want.
>>
>>> -- 
>>> Helmut Leitner    leitner@hls.via.at
>>> Graz, Austria   www.hls-software.com
>>
>>
>>
> 
> 
> 
May 13, 2004
Huh thats weird, i could of swore at one time it was inout, maybe it changed.

Thanks

On Wed, 12 May 2004 17:24:36 -0400, Andrew Edwards <edwardsac@spamfreeusa.org> wrote:

> C wrote:
>> Yes, use 'in' to determine if a key exists, and isnt 'inout' the default anyway ?
>
> No the default is 'in'!
>
>>
>> On Wed, 12 May 2004 14:35:01 -0400, Ben Hinkle <bhinkle@mathworks.com> wrote:
>>
>>>
>>> "Helmut Leitner" <helmut.leitner@wikiservice.at> wrote in message
>>> news:40A266E1.76885A65@wikiservice.at...
>>>
>>>>
>>>>
>>>> Ivan Senji wrote:
>>>> >
>>>> > "Helmut Leitner" <leitner@hls.via.at> wrote in message
>>>> > news:40A23CCD.F78AD327@hls.via.at...
>>>> > > The following small program
>>>> > >
>>>> > >   alias char[] Str;
>>>> > >   alias int [char []] Bag;
>>>> > >
>>>> > >   Bag bag1;
>>>> > >   Bag bag2;
>>>> > >
>>>> > >   void BagAddElem(Bag bag,Str key)
>>>> > >   {
>>>> > >     int count=bag[key];
>>>> > >     if(count>0) {
>>>> > >       bag[key]=count+1;
>>>> > >     } else {
>>>> > >       bag[key.dup]=1;
>>>> > >     }
>>>> > >   }
>>>> >
>>>> > Shouldn't you pass Bag as inout Bag if you are trying to
>>>> > change it inside the function? That is the reason that bag1
>>>> > and bag2 size doesn't change.
>>>>
>>>> Maybe I should use inout (I thought of it as an object pointer,
>>>> not as an array reference), but bag2 *does* change through the
>>>> same interface. The only difference is the initial query of bag2.
>>>
>>>
>>> The statement
>>>   int count=bag2["TEST"];
>>> will add TEST to bag2 with initialized value (which is 0 for int) if it
>>> isn't already in there.
>>> An associative array has the same length field and data pointer fields as a
>>> dynamic array. So when you pass it to a function if the function either
>>> 1) calls rehash, which would reallocate the data pointer or
>>> 2) adds the first element to an unused array (the case you have here)
>>> then you should make the variable "inout" so that those changes are
>>> reflected in the original array - assuming that is what you want.
>>>
>>>> -- Helmut Leitner    leitner@hls.via.at
>>>> Graz, Austria   www.hls-software.com
>>>
>>>
>>>
>>
>>
>>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 13, 2004
"C" <qbert@atari-soldiers.com> wrote in message
news:opr7w18bltaoygh6@news.digitalmars.com
| Huh thats weird, i could of swore at one time it was inout, maybe it
| changed.
|
| Thanks
|
| On Wed, 12 May 2004 17:24:36 -0400, Andrew Edwards
| <edwardsac@spamfreeusa.org> wrote:
|
|| C wrote:
||| Yes, use 'in' to determine if a key exists, and isnt 'inout' the
||| default anyway ?
||
|| No the default is 'in'!
||

For classes it is "inout". For arrays, I don't remember. For the rest, it's "in".

-----------------------
Carlos Santander Bernal


May 13, 2004
Carlos Santander B. wrote:

> "C" <qbert@atari-soldiers.com> wrote in message
> news:opr7w18bltaoygh6@news.digitalmars.com
> | Huh thats weird, i could of swore at one time it was inout, maybe it
> | changed.
> |
> | Thanks
> |
> | On Wed, 12 May 2004 17:24:36 -0400, Andrew Edwards
> | <edwardsac@spamfreeusa.org> wrote:
> |
> || C wrote:
> ||| Yes, use 'in' to determine if a key exists, and isnt 'inout' the
> ||| default anyway ?
> ||
> || No the default is 'in'!
> ||
> 
> For classes it is "inout". For arrays, I don't remember. For the rest, it's "in".

For all types it is "in". To see why classes aren't "inout" try

void foo(Object obj){obj=null;} // change obj in caller? it shouldn't
int main() {
  Object x = new Object();
  foo(x);
  printf("%p\n",x);
  return 0;
}

Object references are passed by value.

> -----------------------
> Carlos Santander Bernal

May 13, 2004
Carlos Santander B. wrote:

>"C" <qbert@atari-soldiers.com> wrote in message
>news:opr7w18bltaoygh6@news.digitalmars.com
>| Huh thats weird, i could of swore at one time it was inout, maybe it
>| changed.
>|
>| Thanks
>|
>| On Wed, 12 May 2004 17:24:36 -0400, Andrew Edwards
>| <edwardsac@spamfreeusa.org> wrote:
>|
>|| C wrote:
>||| Yes, use 'in' to determine if a key exists, and isnt 'inout' the
>||| default anyway ?
>||
>|| No the default is 'in'!
>||
>
>For classes it is "inout". For arrays, I don't remember. For the rest, it's
>"in".
>
>-----------------------
>Carlos Santander Bernal
>
>
>  
>
To be more specific.  Everything is passed as *in* by default.  Its just that arrays and classes are references that allows you be able to modify the data and pass it back.  For instance, what does this do?

class A
{    void func() {  }
}


void func(A a)
{
  a = new A;
}

int main( char[][] args )
{
  A a;
    func(a);
    a.func();

  return 0;
}


-- 
-Anderson: http://badmama.com.au/~anderson/