www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Return a dynamic array: bug or feature?

reply Gilles G. <schaouette free.fr> writes:
Hello,
I went into trouble returning a dynamic array from a function. For example:
    import std.stdio;
    int[] testGood()
    {
        int a[]; a.length=2;
        a[]=1;
        return a;
    }
    
    int[] testBad()
    {
        int a[2];
        a[]=1;
        return a;
    }
    
    int main()
    {
        int b[];
        b = testGood();
        writef("Good test:\n");
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        b = testBad();
        writef("Bad test:\n");
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        return 0;
    }
This code outputs:
Good test:
  b[0]=1,  b[1]=1
  b[0]=1,  b[1]=1
Bad test:
  b[0]=0,  b[1]=1
  b[0]=0,  b[1]=1

I guess this is the good behavior since I should not return a static array from a function, but the compiler _should_ issue a warning here... or not? -- Gilles
Jul 03 2007
parent reply Gilles G. <schaouette free.fr> writes:
Replying to myself...
I just realised that dmd issues an error on the previous code (Error: escaping
reference to local a) while gdc based on dmd 1.007 does not!
However, I really ran into trouble yesterday returning a static array using
dmd. Here is how I do it:
   import std.stdio;
    int[] testGood()
    {
        int a[]; a.length=2;
        a[]=1;
        return a;
    }

    int[] testBad()
    in { /*nothing*/ }
    out{ /*nothing too*/}
    body
    {
        int a[2];
        a[]=1;
        return a;
    }

    int main()
    {
        int b[];
        b = testGood();
        writef("Good test:\n");
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        b = testBad();
        writef("Bad test:\n");
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
        return 0;
    }

Then the DMD will just compile fine and the ouput is
Good test:
  b[0]=1,  b[1]=1
  b[0]=1,  b[1]=1
Bad test:
  b[0]=4280528,  b[1]=4298584
  b[0]=4280472,  b[1]=4280528

So it seems that using the in out and body statement changes the behavior of DMD... Maybe I should file a bug report now. -- Gilles Gilles G. Wrote:
 Hello,
 I went into trouble returning a dynamic array from a function. For example:
     import std.stdio;
     int[] testGood()
     {
         int a[]; a.length=2;
         a[]=1;
         return a;
     }
     
     int[] testBad()
     {
         int a[2];
         a[]=1;
         return a;
     }
     
     int main()
     {
         int b[];
         b = testGood();
         writef("Good test:\n");
         writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
         writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
         b = testBad();
         writef("Bad test:\n");
         writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
         writef("  b[0]=%d,  b[1]=%d\n",b[0],b[1]);
         return 0;
     }
 This code outputs:
Good test:
  b[0]=1,  b[1]=1
  b[0]=1,  b[1]=1
Bad test:
  b[0]=0,  b[1]=1
  b[0]=0,  b[1]=1

I guess this is the good behavior since I should not return a static array from a function, but the compiler _should_ issue a warning here... or not? -- Gilles

Jul 04 2007
parent reply Don Clugston <dac nospam.com.au> writes:
Gilles G. wrote:
 However, I really ran into trouble yesterday returning a static array using
dmd. Here is how I do it:
    import std.stdio;
     int[] testGood()
     {
         int a[]; a.length=2;

    int[] testBad()
         int a[2];

These lines have totally different meanings. The first 'a' is allocated on the heap, the second one on the stack. It has nothing to do with in/out/body.
Jul 04 2007
parent reply Gilles G. <schaouette free.fr> writes:
 These lines have totally different meanings. The first 'a' is allocated on the 
 heap, the second one on the stack. It has nothing to do with in/out/body.

Let me explain once again then. This doesn't compile, and this is _normal_: int[] test() { int a[2]; return a; } But this does compile and should obviously not! int[] test() in{} out{} body { int a[2]; return a; } Therefore, there _is_ a problem with in/out/body. -- Gilles
Jul 04 2007
next sibling parent Don Clugston <dac nospam.com.au> writes:
Gilles G. wrote:
 These lines have totally different meanings. The first 'a' is allocated on the 
 heap, the second one on the stack. It has nothing to do with in/out/body.


Although the testGood() is entirely irrelevant. Yeah, post it in bugzilla. "'body' disables escape analysis", or something.
Jul 04 2007
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 04 Jul 2007 07:47:19 -0400, Gilles G. wrote:

 This doesn't compile, and this is _normal_:
 int[] test()
 {
     int a[2];
     return a;
 }
 But this does compile and should obviously not!
 int[] test()
 in{}
 out{}
 body
 {
     int a[2];
     return a;
 }
 
 Therefore, there _is_ a problem with in/out/body.

Agreed. In fact its the 'out' that's the problem. This doesn't compile ... int[] test() in{} //out{} body { int a[2]; return a; } -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 04 2007