www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - is this the expected output

reply g g <htpp www.com> writes:
Is this code :

import std.stdio;
import std.conv;
struct pt1{
    p val;
    pt1* next;
}
struct p{
    int val;
    string toString(){
        return(to!string(val));
    }
}
void thefun(pt1 x){
    writeln(&x);
}
void main(){
    auto p0 = p(1);
    auto p1 = p(2);
    auto p2 = p(3);
    auto p3 = p(4);
    p[] arr = [p0,p1,p2,p3];
    writeln(arr);
    foreach(r;arr){
        thefun(pt1(r));
    }
}

supposed to output this:

1 2 3 4
BFE61E28
BFE61E28
BFE61E28
BFE61E28 //Note all the addresses are the same

It is expected that using a  struct literal(or default constructor) on a bucle
reuses the same address?
I got hit by this trying to do a tree structure builder, for hours searching
aand finally found this (feature | bug). If so, how I could get a new struct to
void changing (in a unnoticeable way) the same struct i just set.

thanks.
g g
Dec 22 2010
next sibling parent wrzosk <dprogr gmail.com> writes:
I believe that pt1(r) value is created on the stack, then the thefunc is 
called with that value (by Value semantic - so another value is created 
on the stack) and it prints pointer to the value on the stack. Then it 
returnes so the stack values are destroyed, next iteration begins and 
all steps are the same. The addresses of the values are just the same as 
thay were in previous loop. calling the function is deterministic so the 
addresses are also because nothing else stays on the stack between two 
iterations.
On 23.12.2010 00:16, g g wrote:
 Is this code :

 import std.stdio;
 import std.conv;
 struct pt1{
      p val;
      pt1* next;
 }
 struct p{
      int val;
      string toString(){
          return(to!string(val));
      }
 }
 void thefun(pt1 x){
      writeln(&x);
 }
 void main(){
      auto p0 = p(1);
      auto p1 = p(2);
      auto p2 = p(3);
      auto p3 = p(4);
      p[] arr = [p0,p1,p2,p3];
      writeln(arr);
      foreach(r;arr){
          thefun(pt1(r));
      }
 }

 supposed to output this:

 1 2 3 4
 BFE61E28
 BFE61E28
 BFE61E28
 BFE61E28 //Note all the addresses are the same

 It is expected that using a  struct literal(or default constructor) on a bucle
reuses the same address?
 I got hit by this trying to do a tree structure builder, for hours searching
aand finally found this (feature | bug). If so, how I could get a new struct to
void changing (in a unnoticeable way) the same struct i just set.

 thanks.
 g g
Dec 22 2010
prev sibling next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 23.12.2010 2:16, g g wrote:
 Is this code :

 import std.stdio;
 import std.conv;
 struct pt1{
      p val;
      pt1* next;
 }
 struct p{
      int val;
      string toString(){
          return(to!string(val));
      }
 }
Here, notice that thefun is taking pt1 by value - a copy.
 void thefun(pt1 x){
      writeln(&x);
 }
Then you take address of local copy, which is unacceptable. What you probably wanted is this: void thefun(ref pt1 x){//reference to the original , but then it must be lvalue writeln(&x); }
 void main(){
      auto p0 = p(1);
      auto p1 = p(2);
      auto p2 = p(3);
      auto p3 = p(4);
      p[] arr = [p0,p1,p2,p3];
      writeln(arr);
      foreach(r;arr){
          thefun(pt1(r));
      }
 }
But here you pass a rvalue to function that takes address. In fact, it prints the address of temporary place in stack used to hold result of pt1(r).
 supposed to output this:

 1 2 3 4
 BFE61E28
 BFE61E28
 BFE61E28
 BFE61E28 //Note all the addresses are the same

 It is expected that using a  struct literal(or default constructor) on a bucle
reuses the same address?
Yes, inside loop it's likely to use the same address, but actually you didn't took it but an address of a copy of it ;) Which means you need to store these temporaries like pt1(r) somewhere, usually on heap (just as you do with dynamic array of p).
 I got hit by this trying to do a tree structure builder, for hours searching
aand finally found this (feature | bug). If so, how I could get a new struct to
void changing (in a unnoticeable way) the same struct i just set.

 thanks.
 g g
-- Dmitry Olshansky
Dec 22 2010
prev sibling parent reply g g <htpp www.com> writes:
Thanks for the answers
what I did is this ( i feel that it is quite clumsy):

       Node* x = cast(Node*) (GC.malloc(Node.sizeof));
        *x = xa;
        x.up = curnode;
        ...
Dec 22 2010
next sibling parent spir <denis.spir gmail.com> writes:
On Wed, 22 Dec 2010 19:40:16 -0500
g g <htpp www.com> wrote:

 Thanks for the answers
 what I did is this ( i feel that it is quite clumsy):
=20
        Node* x =3D cast(Node*) (GC.malloc(Node.sizeof));
         *x =3D xa;
         x.up =3D curnode;
         ...
This is not that clumsy (except for you naming!). You have to allocate dist= inct memory cells for distinct programming elements that represent distinct= entities in your (mental) modell, haven't you? D provides adequate feature= s that allow you thinking thinking at a higher-level. But if you want to pl= ay at a lower-level, you'll need to juggle with pointer detail issues ;-) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 22 2010
prev sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 23.12.2010 3:40, g g wrote:
 Thanks for the answers
 what I did is this ( i feel that it is quite clumsy):

         Node* x = cast(Node*) (GC.malloc(Node.sizeof));
          *x = xa;
          x.up = curnode;
          ...
which could be improved: Node* x = new Node(...);//paste your constructor args in place of ... if Node has a constructor, or just Node* x = new Node;// if no constructors -- Dmitry Olshansky
Dec 23 2010