www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - struct vs. internal class

reply Charles Hixson <charleshixsn earthlink.net> writes:
I'm not quite clear about how structs are supposed to be used, 
e.g., consider:
class As
{
protected
   struct  B
   {  int  c;
      int  d;
   }
   B[]  bs;
public
   int assign(int e)
   {  B  b;
      b.c  = e;
      b.d  = e + e;
      bs  ~= b;
    }
}

Does that work dependably, of are pieces of the bs array likely 
to be removed by garbage collection?  Should I use:
...
   int assign(int e)
   {  B  b = new B;
...
That looks weird for a struct.  Or should B rather be defined as 
an internal class?  (That would almost certainly work, but I tend 
to think of classes as much heavier than are structs.)

It seems likely that I need to make B an internal class...but if 
it explains this in the documentation, I didn't see it. 
(Actually grepping class.html from dmd/html/d didn't find any 
mentions of internal at all...but I'm certain that I've 
encountered references to them in the newsgroups.)
Jun 22 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 22 Jun 2005 12:44:57 -0700, Charles Hixson  
<charleshixsn earthlink.net> wrote:
 I'm not quite clear about how structs are supposed to be used, e.g.,  
 consider:
 class As
 {
 protected
    struct  B
    {  int  c;
       int  d;
    }
    B[]  bs;
 public
    int assign(int e)
    {  B  b;
       b.c  = e;
       b.d  = e + e;
       bs  ~= b;
     }
 }

 Does that work dependably
I believe the line "bs ~= b;" copies the contents of 'b' into a new B which exists at the end of the array. Meaning a function like this: void assign2(int e) { bs.length = bs.length + 1; bs[$-1].c = e; bs[$-1].d = e + e; } would be slighly more efficient, as it doesn't copy it simply creates in place at the end of the array.
 , or are pieces of the bs array likely to be removed by garbage  
 collection?
'b' will be, the copy won't be. Regan p.s. This code demonstrates what I think happens. Note: bs.ptr changes as it's reallocated (you can stop this by pre-allocating and using an index variable). import std.stdio; class As { protected struct B { int c; int d; } B[] bs; public void assign(int e) { B b; B* p; b.c = e; b.d = e + e; bs ~= b; p = bs.ptr + (bs.length-1); writefln("bs(%x) - (%x){%d,%d} - b(%x)",bs.ptr,p,p.c,p.d,&b); } void assign2(int e) { B* p; bs.length = bs.length + 1; bs[$-1].c = e; bs[$-1].d = e + e; p = bs.ptr + (bs.length-1); writefln("bs(%x) - (%x){%d,%d}",bs.ptr,p,p.c,p.d); } void print() { B* p; writefln(""); for(int i = 0; i < bs.length; i++) { p = bs.ptr + i; writefln("bs(%x) - (%x)",bs.ptr,p,"{",bs[i].c,",",bs[i].d,"}"); } } } void main() { As a = new As(); a.assign(1); a.assign(2); a.assign(3); a.assign(4); a.assign2(5); a.assign2(6); a.assign2(7); a.assign2(8); a.print(); }
Jun 22 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 22 Jun 2005 12:44:57 -0700, Charles Hixson wrote:

 I'm not quite clear about how structs are supposed to be used, 
 e.g., consider:
 class As
 {
 protected
    struct  B
    {  int  c;
       int  d;
    }
    B[]  bs;
 public
    int assign(int e)
    {  B  b;
       b.c  = e;
       b.d  = e + e;
       bs  ~= b;
     }
 }
 
 Does that work dependably, of are pieces of the bs array likely 
 to be removed by garbage collection?  Should I use:
 ...
    int assign(int e)
    {  B  b = new B;
 ...
 That looks weird for a struct.  Or should B rather be defined as 
 an internal class?  (That would almost certainly work, but I tend 
 to think of classes as much heavier than are structs.)
 
 It seems likely that I need to make B an internal class...but if 
 it explains this in the documentation, I didn't see it. 
 (Actually grepping class.html from dmd/html/d didn't find any 
 mentions of internal at all...but I'm certain that I've 
 encountered references to them in the newsgroups.)
Your code seems to work okay. I guess the "bs ~= b" is actually adding a copy of the stack entity 'b' to the 'bs' array. However to totally make it look safer you might code it like this instead ... void assign(int e) { bs.length = bs.length + 1; bs[$-1].c = e; bs[$-1].d = e + e; } No local struct is created in the scope of the 'assign' function that way. -- Derek Parnell Melbourne, Australia 23/06/2005 7:14:19 AM
Jun 22 2005
next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 23 Jun 2005 07:17:15 +1000, Derek Parnell <derek psych.ward> wrote:
    void assign(int e)
    {
       bs.length = bs.length + 1;
       bs[$-1].c  = e;
       bs[$-1].d  = e + e;
    }
<snap>! I was first! ;) Regan
Jun 22 2005
prev sibling parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Derek Parnell wrote:
 On Wed, 22 Jun 2005 12:44:57 -0700, Charles Hixson wrote:
 
 I'm not quite clear about how structs are supposed to be used, 
 e.g., consider:
 class As
 {
 protected
    struct  B
    {  int  c;
       int  d;
    }
    B[]  bs;
 public
    int assign(int e)
    {  B  b;
       b.c  = e;
       b.d  = e + e;
       bs  ~= b;
     }
 }

 Does that work dependably, of are pieces of the bs array likely 
 to be removed by garbage collection?  Should I use:
 ...
    int assign(int e)
    {  B  b = new B;
 ...
 That looks weird for a struct.  Or should B rather be defined as 
 an internal class?  (That would almost certainly work, but I tend 
 to think of classes as much heavier than are structs.)

 It seems likely that I need to make B an internal class...but if 
 it explains this in the documentation, I didn't see it. 
 (Actually grepping class.html from dmd/html/d didn't find any 
 mentions of internal at all...but I'm certain that I've 
 encountered references to them in the newsgroups.)
Your code seems to work okay. I guess the "bs ~= b" is actually adding a copy of the stack entity 'b' to the 'bs' array. However to totally make it look safer you might code it like this instead ... void assign(int e) { bs.length = bs.length + 1; bs[$-1].c = e; bs[$-1].d = e + e; } No local struct is created in the scope of the 'assign' function that way.
Well, I was nervous enough about it that I DID switch to a class based internal structure, where I'm CLEAR that what's happening is pointer manipulation. That way I can trust that it won't be garbage collected/deleted from the stack as long as a pointer to it is live. (If it's actually copying all the data, then I had no need to worry on that score...but I felt/feel unsure.)
Jun 23 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 23 Jun 2005 16:51:23 -0700, Charles Hixson  
<charleshixsn earthlink.net> wrote:
 Derek Parnell wrote:
 On Wed, 22 Jun 2005 12:44:57 -0700, Charles Hixson wrote:

 I'm not quite clear about how structs are supposed to be used, e.g.,  
 consider:
 class As
 {
 protected
    struct  B
    {  int  c;
       int  d;
    }
    B[]  bs;
 public
    int assign(int e)
    {  B  b;
       b.c  = e;
       b.d  = e + e;
       bs  ~= b;
     }
 }

 Does that work dependably, of are pieces of the bs array likely to be  
 removed by garbage collection?  Should I use:
 ...
    int assign(int e)
    {  B  b = new B;
 ...
 That looks weird for a struct.  Or should B rather be defined as an  
 internal class?  (That would almost certainly work, but I tend to  
 think of classes as much heavier than are structs.)

 It seems likely that I need to make B an internal class...but if it  
 explains this in the documentation, I didn't see it. (Actually  
 grepping class.html from dmd/html/d didn't find any mentions of  
 internal at all...but I'm certain that I've encountered references to  
 them in the newsgroups.)
Your code seems to work okay. I guess the "bs ~= b" is actually adding a copy of the stack entity 'b' to the 'bs' array. However to totally make it look safer you might code it like this instead ... void assign(int e) { bs.length = bs.length + 1; bs[$-1].c = e; bs[$-1].d = e + e; } No local struct is created in the scope of the 'assign' function that way.
Well, I was nervous enough about it that I DID switch to a class based internal structure, where I'm CLEAR that what's happening is pointer manipulation. That way I can trust that it won't be garbage collected/deleted from the stack as long as a pointer to it is live. (If it's actually copying all the data, then I had no need to worry on that score...but I felt/feel unsure.)
I am fairly confident that my sample shows what is actually happening. It's more obvious if you preallocate the array and use an index variable to assign new structs to, then the data pointer for the array doesn't move and they all line up as you'd expect. Then again, I *might* be wrong. ;) Regan
Jun 23 2005