Thread overview
ref auto getRange() return scope move struct ?
Aug 16, 2019
Newbie2019
Aug 16, 2019
Newbie2019
Aug 16, 2019
Jonathan M Davis
Aug 16, 2019
Newbie2019
Aug 16, 2019
Jonathan M Davis
Aug 17, 2019
Newbie2019
August 16, 2019
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 ?

August 16, 2019
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 ?


August 16, 2019
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



August 16, 2019
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?




August 16, 2019
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



August 17, 2019
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.