Jump to page: 1 2
Thread overview
UniquePtr in D
Dec 22, 2013
Benjamin Thaut
Dec 22, 2013
Kelet
Dec 22, 2013
Benjamin Thaut
Dec 22, 2013
Benjamin Thaut
Dec 22, 2013
Sergei Nosov
Dec 22, 2013
Benjamin Thaut
Dec 23, 2013
Sergei Nosov
Dec 22, 2013
Timon Gehr
Dec 22, 2013
Timon Gehr
Dec 22, 2013
Timon Gehr
Dec 22, 2013
Timon Gehr
December 22, 2013
When working with C-libraries in D I often wish for a equivalent of the C++11 unique_ptr. Unfortunately this is not possible in D. Consider the following source code:

http://dpaste.dzfl.pl/6e71c815

Is error 1 a bug? Because there should cleary not be any copy at this point.

Should we implement moving of u so that error 2 goes away? The compiler could move u into the function and move back out afterwards, but that would mean that the contents of u would be invalid for the duration of the function call (unsafe?)

Kind Regards
Benjamin Thaut
December 22, 2013
On Sunday, 22 December 2013 at 13:19:48 UTC, Benjamin Thaut wrote:
> When working with C-libraries in D I often wish for a equivalent of the C++11 unique_ptr. Unfortunately this is not possible in D. Consider the following source code:
>
> http://dpaste.dzfl.pl/6e71c815
>
> Is error 1 a bug? Because there should cleary not be any copy at this point.
>
> Should we implement moving of u so that error 2 goes away? The compiler could move u into the function and move back out afterwards, but that would mean that the contents of u would be invalid for the duration of the function call (unsafe?)
>
> Kind Regards
> Benjamin Thaut

Is std.typecons.Unique[1] not the equivalent of unique_ptr?

[1]: http://dlang.org/phobos/std_typecons.html#.Unique

Regards,
Kelet
December 22, 2013
Am 22.12.2013 14:24, schrieb Kelet:
> On Sunday, 22 December 2013 at 13:19:48 UTC, Benjamin Thaut wrote:
>> When working with C-libraries in D I often wish for a equivalent of
>> the C++11 unique_ptr. Unfortunately this is not possible in D.
>> Consider the following source code:
>>
>> http://dpaste.dzfl.pl/6e71c815
>>
>> Is error 1 a bug? Because there should cleary not be any copy at this
>> point.
>>
>> Should we implement moving of u so that error 2 goes away? The
>> compiler could move u into the function and move back out afterwards,
>> but that would mean that the contents of u would be invalid for the
>> duration of the function call (unsafe?)
>>
>> Kind Regards
>> Benjamin Thaut
>
> Is std.typecons.Unique[1] not the equivalent of unique_ptr?
>
> [1]: http://dlang.org/phobos/std_typecons.html#.Unique
>
> Regards,
> Kelet

Well yes, but I'm more interrested in moving around the ownership between functions, which works in c++11 because of the move semantics they implemented. This doesn't work in D for the shown reasons.
December 22, 2013
I also just noticed that std.typecons.Unique does not disable the copy constructor. That doesn't seem very safe to me. The source code for it is also littered with tons of "Doens't work yet" comments.

December 22, 2013
On Sunday, 22 December 2013 at 13:28:05 UTC, Benjamin Thaut wrote:
> Well yes, but I'm more interrested in moving around the ownership between functions, which works in c++11 because of the move semantics they implemented. This doesn't work in D for the shown reasons.

http://dpaste.dzfl.pl/d1a6f7d0

That's as close as I could get. It doesn't move the parameters outside of the function. I workaround it by returning the unique input arguments. It's like "here's your object back".

Everything is pretty much safe in @safe mode - as long as you don't pass Unique values by reference.
December 22, 2013
Am 22.12.2013 14:36, schrieb Sergei Nosov:
> On Sunday, 22 December 2013 at 13:28:05 UTC, Benjamin Thaut wrote:
>> Well yes, but I'm more interrested in moving around the ownership
>> between functions, which works in c++11 because of the move semantics
>> they implemented. This doesn't work in D for the shown reasons.
>
> http://dpaste.dzfl.pl/d1a6f7d0
>
> That's as close as I could get. It doesn't move the parameters outside
> of the function. I workaround it by returning the unique input
> arguments. It's like "here's your object back".
>
> Everything is pretty much safe in @safe mode - as long as you don't pass
> Unique values by reference.

Uh, this looks a lot better then std.typecons.Unique
Did you try doing a pull request to replace std.typecons.Unique with your implementation?

Kind Regards
Benjamin Thaut
December 22, 2013
On 12/22/2013 02:36 PM, Sergei Nosov wrote:
> On Sunday, 22 December 2013 at 13:28:05 UTC, Benjamin Thaut wrote:
>> Well yes, but I'm more interrested in moving around the ownership
>> between functions, which works in c++11 because of the move semantics
>> they implemented. This doesn't work in D for the shown reasons.
>
> http://dpaste.dzfl.pl/d1a6f7d0
>
> That's as close as I could get. It doesn't move the parameters outside
> of the function. I workaround it by returning the unique input
> arguments. It's like "here's your object back".
>
> Everything is pretty much safe in @safe mode - as long as you don't pass
> Unique values by reference.

You probably want to fix this:

class C{}

void main(){
    auto x = unique!C().pack;
    auto y = x.unpack;
    auto z = x.unpack;
    assert(y.irel is z.irel);
}

December 22, 2013
On 12/22/2013 02:19 PM, Benjamin Thaut wrote:
> When working with C-libraries in D I often wish for a equivalent of the
> C++11 unique_ptr. Unfortunately this is not possible in D. Consider the
> following source code:
>
> http://dpaste.dzfl.pl/6e71c815
>
> Is error 1 a bug? Because there should cleary not be any copy at this
> point.
> ...

I don't think the conditions when a struct is moved are actually documented beyond the NRVO case. I think it ideally would be a bug, but this would require some kind of DIP.

> Should we implement moving of u so that error 2 goes away? The compiler
> could move u into the function and move back out afterwards, but that
> would mean that the contents of u would be invalid for the duration of
> the function call (unsafe?)
>
> Kind Regards
> Benjamin Thaut

The problem is that currently variable 'u' needs to be valid in order to be assigned to. It would be better if it was moved into test2 and then reinitialized.

Currently, structs with disabled default construction and postblit are pretty much useless as value types. One has to include some kind of invalid default state. (As Sergei's implementation also does.) Then it is always possible to use explicit moves:

import core.stdc.stdio;
import std.algorithm;

struct UniquePtr{
    private int m_i;
    private bool _valid=false;
    @property bool valid(){ return valid; }
    @disable this(this);

    this(int i){
        m_i = i;
        _valid = true;
    }

    ~this(){
        if(_valid) printf("deleting %d\n", m_i);
    }
}

UniquePtr test1(){
    auto u = UniquePtr(5);
    return u;
}

UniquePtr test2(UniquePtr u){
    return move(u);
}

void main(string[] args){
    auto u = test1();
    u = test2(move(u));
}

December 22, 2013
On 12/22/2013 03:13 PM, Timon Gehr wrote:
>>
>> Is error 1 a bug? Because there should cleary not be any copy at this
>> point.
>> ...
>
> I don't think the conditions when a struct is moved are actually
> documented beyond the NRVO case. I think it ideally would be a bug, but
> this would require some kind of DIP.

The main issue would probably be internal pointers in @safe code.
December 22, 2013
On 12/22/2013 03:19 PM, Timon Gehr wrote:
> On 12/22/2013 03:13 PM, Timon Gehr wrote:
>>>
>>> Is error 1 a bug? Because there should cleary not be any copy at this
>>> point.
>>> ...
>>
>> I don't think the conditions when a struct is moved are actually
>> documented beyond the NRVO case. I think it ideally would be a bug, but
>> this would require some kind of DIP.
>
> The main issue would probably be internal pointers in @safe code.

Scrap that, it would be disallowed to create them in @safe code anyway, and hence the memory corruption would be attributed to the @system code that created the pointer.
« First   ‹ Prev
1 2