www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Two bugs found: GC bug as well as scope delegate bug

reply Mehrdad <wfunction hotmail.com> writes:
Something always told me the I can't trust D's GC, the way the working 
set always grew (even though people always claimed that's not a good 
measure of anything)... now I think I finally have proof. :)

I believe I've found at least two behaviors, neither of which should happen:

1. I should NOT get an OutOfMemory error.
2. There should NOT be a GC allocation anywhere in the first place -- 
everything is well-scoped, and I've used the 'scope' modifier.
3. If the compiler isn't respecting 'scope' on a parameter, it should 
IMHO give at _least_ a warning (if not an error, which would be more 
desirable).

Code:

         void enumerate(T)(T[] items, scope void delegate(T) sink)  // 
I've said 'scope', but the compiler doesn't respect it.
         {
                 foreach (item; items)
                         sink(item);
         }

         struct Temp(T)
         {
                 T[] buf;
                 void test(T[] items)
                 {
                         for (;;)
                                 enumerate(items, delegate(T item) { 
this.buf ~= item; });  //The compiler thinks that the scope of this.buf 
is escaped, but it's not
                 }
         }

         void main()
         {
                 int[10] buf;
                 Temp!int().test(buf);
         }

I ran this on a nightly pull of DMD 2.054 (perhaps the bugs have been 
fixed?). When I run this, the program crashs with an out of memory error 
(after allocating around a gigabyte of RAM).

Are these actually 2-3 bugs, or am I missing something?
Aug 06 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
Everyone, apologies for this in hindsight, it's quite ridiculous. x_____x

In trying to reproduce a similar bug I saw in my code, I made a 
completely stupid example which made no sense.

I'll proofread better next time, hopefully I can isolate it then.
Aug 06 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 7, 11 14:47, Mehrdad wrote:
 Everyone, apologies for this in hindsight, it's quite ridiculous. x_____x

 In trying to reproduce a similar bug I saw in my code, I made a
 completely stupid example which made no sense.

 I'll proofread better next time, hopefully I can isolate it then.
Next time you should file the bug directly to bugzilla (http://d.puremagic.com/issues/).
Aug 07 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 8/7/2011 1:15 AM, KennyTM~ wrote:
 On Aug 7, 11 14:47, Mehrdad wrote:
 Everyone, apologies for this in hindsight, it's quite ridiculous. 
 x_____x

 In trying to reproduce a similar bug I saw in my code, I made a
 completely stupid example which made no sense.

 I'll proofread better next time, hopefully I can isolate it then.
Next time you should file the bug directly to bugzilla (http://d.puremagic.com/issues/).
OK sure.
Aug 07 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
OK so apparently the GC was working fine, my bad.
I'm not sure about the compiler, though.

When I have this code:

     void foo(int a, scope void delegate(int) sink)
     {
         sink(a);
     }
     void main()
     {
         int tmp;
         foo(5, delegate(int c) { tmp = c; });
     }

I get a heap allocation as soon as main() is entered. It only happens 
because of the closure.
Why does this happen? Isn't the whole point of "scope" to prevent this?
(I didn't post this on the bug tracking system since I'm not sure if 
it's by design or not.)
Aug 07 2011
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 08 Aug 2011 03:17:13 +0200, Mehrdad <wfunction hotmail.com> wrote:

 OK so apparently the GC was working fine, my bad.
 I'm not sure about the compiler, though.

 When I have this code:

      void foo(int a, scope void delegate(int) sink)
      {
          sink(a);
      }
      void main()
      {
          int tmp;
          foo(5, delegate(int c) { tmp = c; });
      }

 I get a heap allocation as soon as main() is entered. It only happens  
 because of the closure.
 Why does this happen? Isn't the whole point of "scope" to prevent this?
 (I didn't post this on the bug tracking system since I'm not sure if  
 it's by design or not.)
'scope' in the position you have it, will not prevent this, no. Instead, it will have to be used upon declaring the delegate, like this: void bar(int a, scope void delegate(int) sink) { sink(a); } void main() { int tmp; scope fn = (int c) { tmp = c; }; bar(5, fn); } -- Simen
Aug 08 2011
parent reply %u <wfunction hotmail.com> writes:
 'scope' in the position you have it, will not prevent this, no.
What is the purpose of 'scope' in the parameter list?
Aug 08 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
AFAIK it disallows you to escape a reference. `in` is actually const scope.
Aug 08 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 8/8/2011 4:50 PM, Andrej Mitrovic wrote:
 AFAIK it disallows you to escape a reference. `in` is actually const scope.
So this heap allocation shouldn't be happening, right?
Aug 08 2011
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 09 Aug 2011 03:36:15 +0200, Mehrdad <wfunction hotmail.com> wrote:

 On 8/8/2011 4:50 PM, Andrej Mitrovic wrote:
 AFAIK it disallows you to escape a reference. `in` is actually const  
 scope.
So this heap allocation shouldn't be happening, right?
Yes and no. Disallowing that allocation would be an optimization not required by the language. Essentially, 'scope' in the parameter list is a limitation for the callee, not a guarantee for the caller. -- Simen
Aug 08 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 8/8/2011 11:08 PM, Simen Kjaeraas wrote:
 On Tue, 09 Aug 2011 03:36:15 +0200, Mehrdad <wfunction hotmail.com> 
 wrote:

 On 8/8/2011 4:50 PM, Andrej Mitrovic wrote:
 AFAIK it disallows you to escape a reference. `in` is actually const 
 scope.
So this heap allocation shouldn't be happening, right?
Yes and no. Disallowing that allocation would be an optimization not required by the language. Essentially, 'scope' in the parameter list is a limitation for the callee, not a guarantee for the caller.
Hm... at the very least, though, the compiler should generate a bug. Otherwise 'scope' becomes useless like 'inline'.
Aug 09 2011
parent Mehrdad <wfunction hotmail.com> writes:
On 8/9/2011 9:53 PM, Mehrdad wrote:
 On 8/8/2011 11:08 PM, Simen Kjaeraas wrote:
 On Tue, 09 Aug 2011 03:36:15 +0200, Mehrdad <wfunction hotmail.com> 
 wrote:

 On 8/8/2011 4:50 PM, Andrej Mitrovic wrote:
 AFAIK it disallows you to escape a reference. `in` is actually 
 const scope.
So this heap allocation shouldn't be happening, right?
Yes and no. Disallowing that allocation would be an optimization not required by the language. Essentially, 'scope' in the parameter list is a limitation for the callee, not a guarantee for the caller.
Hm... at the very least, though, the compiler should generate a bug. Otherwise 'scope' becomes useless like 'inline'.
OOPS I meant 'warning' not 'bug', typo.
Aug 09 2011