www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ref auto getRange() return scope move struct ?

reply Newbie2019 <newbie2019 gmail.com> writes:
I has this simple function has some memory bugs:

-------
struct TreeRange {
	 disable this() ;
	 disable this(this) ;
}
struct Tree {
	ref auto getRange() return scope {
		return TreeRange!T(_root);
	}
}
Tree tree;
auto range = tree.getRange();
------

when I trace the issue, I find the address for TreeRange is 
moved.  it TreeRange.__ctor the address is 0x7ffeefbfd168,   but 
"auto range = tree.getRange();" address is 0x7ffeefbfd420


How to prevent this struct move in this case ?
Aug 16 2019
parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Friday, 16 August 2019 at 12:23:01 UTC, Newbie2019 wrote:
 I has this simple function has some memory bugs:

 -------
 struct TreeRange {
 	 disable this() ;
 	 disable this(this) ;
 }
 struct Tree {
 	ref auto getRange() return scope {
 		return TreeRange!T(_root);
 	}
 }
 Tree tree;
 auto range = tree.getRange();
 ------

 when I trace the issue, I find the address for TreeRange is 
 moved.  it TreeRange.__ctor the address is 0x7ffeefbfd168,   
 but "auto range = tree.getRange();" address is 0x7ffeefbfd420


 How to prevent this struct move in this case ?
With dip1014 I can fix the internal pointer(but I guess It will need maybe 1 years late to implement). Right now I just want forbit the move action, is it doable ?
Aug 16 2019
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, August 16, 2019 6:29:19 AM MDT Newbie2019 via Digitalmars-d-learn 
wrote:
 On Friday, 16 August 2019 at 12:23:01 UTC, Newbie2019 wrote:
 I has this simple function has some memory bugs:

 -------
 struct TreeRange {

      disable this() ;
      disable this(this) ;

 }
 struct Tree {

     ref auto getRange() return scope {

         return TreeRange!T(_root);

     }

 }
 Tree tree;
 auto range = tree.getRange();
 ------

 when I trace the issue, I find the address for TreeRange is
 moved.  it TreeRange.__ctor the address is 0x7ffeefbfd168,
 but "auto range = tree.getRange();" address is 0x7ffeefbfd420


 How to prevent this struct move in this case ?
With dip1014 I can fix the internal pointer(but I guess It will need maybe 1 years late to implement). Right now I just want forbit the move action, is it doable ?
It is not possible to prevent moving in D as things currently stand. DIP 1014 will need to be implemented to either hook into moves or to prevent them. However, once DIP 1014 has been implemented, I would expect the result to be that what you're trying to do here simply wouldn't work if you disallowed moving, since DIP 1014 doesn't affect when the compiler does a move. It just allows you to hook into when a move takes place so that you can do stuff like adjust pointers, and presumably, if you disable the function that hooks into the move, moving will then be disabled (though IIRC, that's not explicitly called out in DIP 1014; it's just what would naturally fall out from how disable works). - Jonathan M Davis
Aug 16 2019
parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Friday, 16 August 2019 at 13:51:49 UTC, Jonathan M Davis wrote:
 It is not possible to prevent moving in D as things currently 
 stand. DIP 1014 will need to be implemented to either hook into 
 moves or to prevent them. However, once DIP 1014 has been 
 implemented, I would expect the result to be that what you're 
 trying to do here simply wouldn't work if you disallowed 
 moving, since DIP 1014 doesn't affect when the compiler does a 
 move. It just allows you to hook into when a move takes place 
 so that you can do stuff like adjust pointers, and presumably, 
 if you  disable the function that hooks into the move, moving 
 will then be disabled (though IIRC, that's not explicitly 
 called out in DIP 1014; it's just what would naturally fall out 
 from how  disable works).

 - Jonathan M Davis
Thanks for the very helpful explain, I will try find some work around to fix this. One more question: If the struct has " disable this() ; disable this(this) ;", and the instance is stored into other struct member or local|global vars, it will never moved again?
Aug 16 2019
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, August 16, 2019 8:14:52 AM MDT Newbie2019 via Digitalmars-d-learn 
wrote:
 On Friday, 16 August 2019 at 13:51:49 UTC, Jonathan M Davis wrote:
 It is not possible to prevent moving in D as things currently
 stand. DIP 1014 will need to be implemented to either hook into
 moves or to prevent them. However, once DIP 1014 has been
 implemented, I would expect the result to be that what you're
 trying to do here simply wouldn't work if you disallowed
 moving, since DIP 1014 doesn't affect when the compiler does a
 move. It just allows you to hook into when a move takes place
 so that you can do stuff like adjust pointers, and presumably,
 if you  disable the function that hooks into the move, moving
 will then be disabled (though IIRC, that's not explicitly
 called out in DIP 1014; it's just what would naturally fall out
 from how  disable works).

 - Jonathan M Davis
Thanks for the very helpful explain, I will try find some work around to fix this. One more question: If the struct has " disable this() ; disable this(this) ;", and the instance is stored into other struct member or local|global vars, it will never moved again?
disable this() disables default initialization and disable this(this) disables copying. Neither of them has anything to do with moving. If you stick a struct in another struct, and the outer struct is moved, then the inner struct is moved, because it's part of the outer struct. A static variable shouldn't ever be moved by the compiler, though anyone could choose to use std.algorithm's move on it. Similarly, if you put an object on the heap, the compiler isn't going to move it. If it were inside a dynamic array, then the runtime might copy it (though if you've disabled default initialization or copying, I don't think that the type can be put in a dynamic array), but aside from std.algorithm's move (or another function that does something similar), it shouldn't ever end up being moved. - Jonathan M Davis
Aug 16 2019
parent Newbie2019 <newbie2019 gmail.com> writes:
On Friday, 16 August 2019 at 16:22:27 UTC, Jonathan M Davis wrote:
 [...]
Thanks very much again, very helpful explain. I use pass by ref scope instead "return TreeRange.__ctor();" to workround this issue.
Aug 16 2019