move object from heap to stack

Johannes Pfau nospam at example.com
Thu Sep 20 03:21:22 PDT 2012


Am Thu, 20 Sep 2012 12:06:28 +0200
schrieb "monarch_dodra" <monarchdodra at gmail.com>:

> On Thursday, 20 September 2012 at 08:10:36 UTC, Namespace wrote:
> > You're right.
> > This is my next try: http://dpaste.dzfl.pl/02b32d33
> > Do you have anything else to say? :)
> 
> I think it looks good, but I'm unsure about "move", or allowing 
> pass by value:
> 
> Classes can't be memcopied the way structs can: Class may have 
> default constructors, or copy constructors, which would be 
> totally ignored by a memcopy. For example, if your class had a 
> "RefCounted" member, its postblit would never be called, and it 
> would then be "over destroyed":
> 
> --------
> class A
> {
>      RefCounted!int rf;
>      this()
>      {
>          rf.RefCounted.ensureInitialized();
>          rf = 5;
>      }
> }
> 
> void main()
> {
>      A a = new A();
>      OnStack!A osa = OnStack!A.move(a);
> }
> --------
> core.exception.InvalidMemoryOperationError
> --------
> Here, osa makes a binary copy of the RefCounted, so the count 
> stays at 1.
> Then, when osa is destroyed, it deletes the RefCounted's store.
> However, when a is destroyed, it still has a pointer to the 
> (deleted) store, creating the Error...
> 
> I think "move" has to go, because classes are just not moveable. 
> pass by value can stay, if and only if, T gives a copy 
> constructor. Or NO constructors (in which case a memcopy should 
> be the same as a default copy).

http://dlang.org/struct.html
D classes do not really have copy constructors. You could assume that
if a constructor has only one argument and it's of the same type as the
class, it's a copy constructor. But that's a pure convention then,
nothing than could be enforced in any way. Copying classes is
dangerous, and problems can also happen without constructors:

----------
class A
{
    void* handle;

    ~this()
    {
        if(handle)
            free(handle);
    }
}

{
auto a = OnStack!A();
a.handle = someHandle;
auto b = a; //copy
} //end of scope, someHandle is freed twice
----------

This can even happen if the class does not keep any reference types.
The example would also be valid with a file handle (uint).



More information about the Digitalmars-d-learn mailing list