www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ref return function using foreach ref result segfaults. Compiler bug?

reply "Rob T" <rob ucora.com> writes:
Hard to describe this problem, see code and read comments below.

class A
{
    private int _v;
	
    this( int a_v )
    {
       _v = a_v;
    }

     property size_t length()
    {
    	return 1;
    }
    int opApply( int delegate( ref int a_v ) a_dg )
    {
       int result = 0;
       for ( ulong i = 0; i < length; ++i )
       {
          result = a_dg( this.opIndex( i ) );
          if ( result ) break;
       }
       return result;
    }
    ref int opIndex( size_t a_iPos )
    {
       return _v;
    }

}

class B : A
{
    this( int a_v )
    {
       super(a_v);
    }

    ref int find( int a_What )
    {
       foreach( val; super )
       {
          if ( val == a_What )
             return val;
       }
       throw new Exception("value not found");
    }
}

main()
{
     auto v_B = new B(500);
     writefln("Search = %d", v_B.find(500) );
     return 0;
}


When the return value of find() is ref, it segfaults or returns 
garbage. If the return value is a copy it works OK.

The only oddity I can see is that 'val' goes out of scope, but 
it's a ref return value (pointer) to _v (right?), so it should 
work anyway.

This looks like a bug in the compiler to me.

What do you guys think?

--rt
Nov 13 2012
parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
On Tuesday, 13 November 2012 at 08:50:16 UTC, Rob T wrote:
 Hard to describe this problem, see code and read comments below.

 class A
 {
    private int _v;
 	
    this( int a_v )
    {
       _v = a_v;
    }

     property size_t length()
    {
    	return 1;
    }
    int opApply( int delegate( ref int a_v ) a_dg )
    {
       int result = 0;
       for ( ulong i = 0; i < length; ++i )
       {
          result = a_dg( this.opIndex( i ) );
          if ( result ) break;
       }
       return result;
    }
    ref int opIndex( size_t a_iPos )
    {
       return _v;
    }

 }

 class B : A
 {
    this( int a_v )
    {
       super(a_v);
    }

    ref int find( int a_What )
    {
       foreach( val; super )
       {
          if ( val == a_What )
             return val;
       }
       throw new Exception("value not found");
    }
 }

 main()
 {
     auto v_B = new B(500);
     writefln("Search = %d", v_B.find(500) );
     return 0;
 }


 When the return value of find() is ref, it segfaults or returns 
 garbage. If the return value is a copy it works OK.

 The only oddity I can see is that 'val' goes out of scope, but 
 it's a ref return value (pointer) to _v (right?), so it should 
 work anyway.

 This looks like a bug in the compiler to me.

 What do you guys think?
This issue looks like bug8093. http://d.puremagic.com/issues/show_bug.cgi?id=8093 And the code works correctly in git head (dmd2.061alpha). Therefore, I think that the bug is fixed very recently. Kenji Hara
Nov 13 2012
parent "Rob T" <rob ucora.com> writes:
On Tuesday, 13 November 2012 at 12:31:26 UTC, Kenji Hara wrote:
 This issue looks like bug8093.
 http://d.puremagic.com/issues/show_bug.cgi?id=8093

 And the code works correctly in git head (dmd2.061alpha). 
 Therefore, I think that the bug is fixed very recently.

 Kenji Hara
Thanks for the response Kenji! I'll implement a work-a-round for now and won't bother filing a bug report. --rt
Nov 13 2012