Jump to page: 1 27  
Page
Thread overview
Move Constructors - Converting Lvalues to Rvalues
5 days ago
Walter Bright
5 days ago
Bastiaan Veelo
5 days ago
Walter Bright
4 days ago
Manu
5 days ago
Dukc
5 days ago
Walter Bright
5 days ago
Walter Bright
4 days ago
Walter Bright
4 days ago
Manu
5 days ago
Dukc
4 days ago
Walter Bright
4 days ago
Dukc
4 days ago
Manu
5 days ago
Timon Gehr
5 days ago
Walter Bright
5 days ago
Per Nordlöw
5 days ago
Walter Bright
5 days ago
Per Nordlöw
5 days ago
Dukc
4 days ago
Walter Bright
4 days ago
Timon Gehr
3 days ago
Walter Bright
3 days ago
Manu
3 days ago
Timon Gehr
3 days ago
Manu
3 days ago
Timon Gehr
3 days ago
Timon Gehr
3 days ago
Timon Gehr
3 days ago
Timon Gehr
4 days ago
Imperatorn
4 days ago
Dukc
4 days ago
Timon Gehr
3 days ago
Walter Bright
3 days ago
Timon Gehr
2 days ago
Imperatorn
2 days ago
ryuukk_
2 days ago
Dukc
2 days ago
Walter Bright
2 days ago
Timon Gehr
2 days ago
RazvanN
3 days ago
Imperatorn
3 days ago
Manu
3 days ago
Timon Gehr
2 days ago
Walter Bright
2 days ago
Timon Gehr
2 days ago
Manu
2 days ago
Manu
5 days ago
Atila Neves
4 days ago
Atila Neves
5 days ago
Walter Bright
4 days ago
Vindex9
4 days ago
Manu
5 days ago
I've been implementing move constructors. They are working, at least on my test cases so far. They are distinguished by a copy constructor takes its argument by ref, and a move constructor by value:

```
struct S
{
    this(ref S); // copy constructor
    this(S);     // move constructor
}
```
So far, so good. Consider:
```
void phone(S s)
{
    S t = s;  // copy constructor
}
```
But what if we want to initialize `t` via a move constructor? Somehow, `s` has to be converted from an lvalue to an rvalue. This is done via the function rvalue():
```
S rvalue(ref S s) { return s; }

S t = rvalue(s);
```
Unfortunately, rvalue() gives us this:
```
S __copytmp = 0;
this(&__copytmp,&s);  // copy construction of s
*__H1D1 = __copytmp;
return __H1D1;
```
which is correct, but not what we want, which is:
```
return &s;
```
and also not pass an extra hidden parameter for the return value, aka __H1D1.

I have thought of several ways to do this, none of which seem particularly attractive as they are all not expressible in conventional D. I won't say what they are in order to not bias anyone.

So, does anyone have any brilliant ideas for how to make the compiler treat an lvalue as an rvalue?

P.S. C++ uses the std::move function to do it:

https://learn.microsoft.com/en-us/cpp/standard-library/utility-functions?view=msvc-170#move

which relies on rvalue references:

https://learn.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp?view=msvc-170

which is a major feature which I prefer to avoid.
5 days ago
On Monday, 30 September 2024 at 16:05:16 UTC, Walter Bright wrote:
[...]
> P.S. C++ uses the std::move function to do it:
>
> https://learn.microsoft.com/en-us/cpp/standard-library/utility-functions?view=msvc-170#move
>
> which relies on rvalue references:
>
> https://learn.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp?view=msvc-170
>
> which is a major feature which I prefer to avoid.

I suppose `-preview=rvaluerefparam` is not relevant here, right?

-- Bastiaan.
5 days ago

On Monday, 30 September 2024 at 16:05:16 UTC, Walter Bright wrote:

>

So, does anyone have any brilliant ideas for how to make the compiler treat an lvalue as an rvalue?

Doesn't core.lifetime.move already do this?

5 days ago
On 9/30/24 18:05, Walter Bright wrote:
> 
> So, does anyone have any brilliant ideas for how to make the compiler treat an lvalue as an rvalue?

Well, with DIP1040 this is automatically the case for last uses.

So in your code example:

```
void phone(S s)
{
    S t = s;  // copy constructor
}
```

The comment is actually inaccurate with DIP1040. With DIP1040, this is a move.


Otherwise, maybe expose explicit moves. This is useful generally. Can just be `move(x)`, where `move` is either special, or is a function with a "move by default" attribute on its parameter, as we discussed previously.
5 days ago
I suspect that we're going in an entirely wrong direction with move constructors for two reasons:

1. Nobody has been able to answer what the purpose of them is, is it an optimization, is it ownership transfer system (which is better done with isolated).
2. @move on the parameter. This can be inferred, AND applies to other functions like swap for escape analysis and opAssign!

```d
struct S {
	this(@move ref S s) { // copy constructor with the /side effect/ of invaliding the original, call dependent
		s = S.init; // compiler removes this if seen
	}
}

void phone(S s1) {
	S s2 = s1; // only one of these has to invalidate s1
	S s3 = s1;
}
```

I strongly believe not going the attribute route is blocking us in for worse behaviors.
5 days ago
On Monday, 30 September 2024 at 17:27:25 UTC, Bastiaan Veelo wrote:
>
> I suppose `-preview=rvaluerefparam` is not relevant here, right?
>
> -- Bastiaan.

Yes, I kinda expected something like std::move explicit thing.

5 days ago
On Monday, 30 September 2024 at 20:28:05 UTC, Richard (Rikki) Andrew Cattermole wrote:
> I suspect that we're going in an entirely wrong direction with move constructors for two reasons:
>
> 1. Nobody has been able to answer what the purpose of them is, is it an optimization, is it ownership transfer system (which is better done with isolated).

My understanding is that we need SSA in order to implement isolated. And so for now I'd say it's an optimisation mostly, but also bug prevention with move-only types.

5 days ago
On 01/10/2024 3:58 PM, Atila Neves wrote:
> On Monday, 30 September 2024 at 20:28:05 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> I suspect that we're going in an entirely wrong direction with move constructors for two reasons:
>>
>> 1. Nobody has been able to answer what the purpose of them is, is it an optimization, is it ownership transfer system (which is better done with isolated).
> 
> My understanding is that we need SSA in order to implement isolated. And so for now I'd say it's an optimisation mostly, but also bug prevention with move-only types.

SSA? What? That has nothing to do with it.

If you want isolated to not have its own analysis you need type state analysis, which is DFA. The same DFA we should be using for escape analysis.

Forward pass only on success.

One of my concerns for move constructors is the addition of analysis that is in addition to the escape analysis DFA.

5 days ago
On 9/30/2024 12:37 PM, Timon Gehr wrote:
> On 9/30/24 18:05, Walter Bright wrote:
>>
>> So, does anyone have any brilliant ideas for how to make the compiler treat an lvalue as an rvalue?
> 
> Well, with DIP1040 this is automatically the case for last uses.

The trouble with last uses is detecting them. It's a variation on live variable DFA, which the optimizer does for variables. Indirections cannot be reliably tracked, and variables which have their address taken similarly can't reliably have DFA done on them.

In any case, I decided for at least the first implementation to require an explicit "convert to rvalue" operation to get the benefits of a move construction. I'm pretty sure it will deliver most of what we want.

5 days ago
On 9/30/2024 1:28 PM, Richard (Rikki) Andrew Cattermole wrote:
> 1. Nobody has been able to answer what the purpose of them is

Performance.

« First   ‹ Prev
1 2 3 4 5 6 7