May 17, 2018
On Thursday, 17 May 2018 at 13:50:26 UTC, Shachar Shemesh wrote:
> There is no such use case. Please remember that at the time opPostMove is called, both new and old memory are still allocated.

That's an interesting moment too. A struct that was supposed to be moved is copied instead and exists in two places simultaneously. Can't tell it yet, but it can have a hole in type system and opPostMove can only be trusted, not safe.
May 17, 2018
On 17/05/18 18:47, kinke wrote:
> On Thursday, 17 May 2018 at 15:23:50 UTC, kinke wrote:
>> See IR for https://run.dlang.io/is/1JIsk7.
> 
> I should probably emphasize that the LLVM `byval` attribute is strange at first sight. Pseudo-IR `void foo(S* byval param); ... foo(S* byarg arg);` doesn't mean that the IR callee gets the S* pointer from the IR callsite; it means 'memcpy(param, arg, S.sizeof)', with `param` being an *implicit* address in foo's parameters stack (calculated by LLVM and so exposed to the callee only). That's the difficulty for LDC I mentioned earlier.

I understand there might be difficulty, but I strongly protest the idea that it is not possible, for one very simple reason: C++.

class Movable {
  int member;

public:
  Movable();

  Movable( const Movable &rhs ); // Copy constructor
  Movable( Movable &&rhs ); // Move constructor
}

Since clang is able to compile this struct and do everything with it, and since the existence of the move constructor requires the precise same type of hooking as is needed in this case, I tend to believe that an IR representation of DIP 1014 is possible.

Shachar
May 17, 2018
On 17/05/18 19:08, Kagamin wrote:
> On Thursday, 17 May 2018 at 13:50:26 UTC, Shachar Shemesh wrote:
>> There is no such use case. Please remember that at the time opPostMove is called, both new and old memory are still allocated.
> 
> That's an interesting moment too. A struct that was supposed to be moved is copied instead and exists in two places simultaneously. Can't tell it yet, but it can have a hole in type system and opPostMove can only be trusted, not safe.

It is a hole (of sorts) in the type system, in that "old" is not going to have a destructor run on its code.

With that said, just because the code is not safe, does not mean it is not @safe.

The only inherent non @safe thing we advocate here is if you want to be able to move const/immutable structs, in which case DIP 1014 advocates casting the constness away. That will, of course, have to be either @system or @trusted.

Shachar
May 17, 2018
On 17 May 2018 at 01:12, Mike Parker via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> This is the review thread for the first Community Review round for DIP 1014, "Hooking D's struct move semantics".
>
> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on May 31, or when I make a post declaring it complete.
>
> At the end of Round 1, if further review is deemed necessary, the DIP will be scheduled for another round. Otherwise, it will be queued for the formal review and evaluation by the language maintainers.
>
> Please familiarize yourself with the documentation for the Community Review before participating.
>
> https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#community-review
>
> Thanks in advance to all who participate.
>
> Destroy!

This is great!
I've wanted this on numerous occasions when interacting with C++ code.
This will make interaction more complete.

Within self-contained D code, I have avoided self-pointers by using self-offsets instead in the past (a bit hack-ey). But this nicely tidies up one more little rough-edge in the language.

:+1:
May 17, 2018
On 17/05/18 22:29, Manu wrote:
> 
> This is great!
> I've wanted this on numerous occasions when interacting with C++ code.
> This will make interaction more complete.
> 
> Within self-contained D code, I have avoided self-pointers by using
> self-offsets instead in the past (a bit hack-ey). But this nicely
> tidies up one more little rough-edge in the language.
> 
> :+1:
> 

Following Andrei's advice, I've actually started writing a couple of examples to illustrate why this is needed.

The first was this:

struct S {
  static int global;
  int local;

  Something selector; // Decides whether we want local or global.
}

Let's further assume that we have an array of S instances with random uniform distribution between local and global.

Obviously, Something can be an enum or a boolean. If it is, however, then we have to perform a condition to select the correct value. The problem with conditionals is that if the CPU misses a guess about what they are (and in our case, the CPU is going to miss about 50% of the time), they are extremely expensive to evaluate.

Performance wise, a much saner approach is:
alias Something = int*;

Of course, this means our struct now has a self referencing pointer.

What I'm getting at is that even if there are alternatives to structs pointing at themselves, they may not be performance wise comparable to pointers.

Of course, the second example was a struct that has no internal pointers, but rather maintains global pointers pointing to it. This problem is quite a bit harder to solve.

Shachar
May 17, 2018
On 17 May 2018 at 13:25, Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 17/05/18 22:29, Manu wrote:
>>
>>
>> This is great!
>> I've wanted this on numerous occasions when interacting with C++ code.
>> This will make interaction more complete.
>>
>> Within self-contained D code, I have avoided self-pointers by using self-offsets instead in the past (a bit hack-ey). But this nicely tidies up one more little rough-edge in the language.
>>
>> :+1:
>>
>
> Following Andrei's advice, I've actually started writing a couple of examples to illustrate why this is needed.
>
> The first was this:
>
> struct S {
>   static int global;
>   int local;
>
>   Something selector; // Decides whether we want local or global.
> }
>
> Let's further assume that we have an array of S instances with random uniform distribution between local and global.
>
> Obviously, Something can be an enum or a boolean. If it is, however, then we have to perform a condition to select the correct value. The problem with conditionals is that if the CPU misses a guess about what they are (and in our case, the CPU is going to miss about 50% of the time), they are extremely expensive to evaluate.
>
> Performance wise, a much saner approach is:
> alias Something = int*;
>
> Of course, this means our struct now has a self referencing pointer.
>
> What I'm getting at is that even if there are alternatives to structs pointing at themselves, they may not be performance wise comparable to pointers.
>
> Of course, the second example was a struct that has no internal pointers, but rather maintains global pointers pointing to it. This problem is quite a bit harder to solve.
>
> Shachar

Oh yeah, I totally recognise that there are instances where a local
offset is not a solution, I was just saying how I've managed to
avoided dealing with this issue before, and not that I loved doing so
that way ;)
This would be a very welcome fix, particularly in code where I
interact with C++!
May 18, 2018
On Thursday, 17 May 2018 at 19:13:48 UTC, Shachar Shemesh wrote:
> The only inherent non @safe thing we advocate here is if you want to be able to move const/immutable structs, in which case DIP 1014 advocates casting the constness away. That will, of course, have to be either @system or @trusted.

There's an idea to give const postblit ability to write, but it's difficult to make such exception for operator method, a possible syntax can be `this(this, const ref S prev)`
May 18, 2018
On Thursday, 17 May 2018 at 20:25:26 UTC, Shachar Shemesh wrote:
> Obviously, Something can be an enum or a boolean. If it is, however, then we have to perform a condition to select the correct value. The problem with conditionals is that if the CPU misses a guess about what they are (and in our case, the CPU is going to miss about 50% of the time), they are extremely expensive to evaluate.
>
> Performance wise, a much saner approach is:
> alias Something = int*;
>
> Of course, this means our struct now has a self referencing pointer.
>
> What I'm getting at is that even if there are alternatives to structs pointing at themselves, they may not be performance wise comparable to pointers.


It's possible to do a branchless condition that chooses between two pointers. I think if the hardware (and compiler) support it it'll just optimize down to a "cmov".


May 18, 2018
On Thursday, 17 May 2018 at 19:11:27 UTC, Shachar Shemesh wrote:
> On 17/05/18 18:47, kinke wrote:
> Since clang is able to compile this struct and do everything with it, and since the existence of the move constructor requires the precise same type of hooking as is needed in this case, I tend to believe that an IR representation of DIP 1014 is possible.

I checked, and the reason is that D and C++ use a different ABI wrt. by-value passing of non-POD arguments. C++ indeed passes a reference to a caller-allocated rvalue, not just on Win64; that makes it trivial, as there are no moves across call boundaries. But your proposal may imply changing the D ABI accordingly.
May 19, 2018
On 18/05/18 22:57, kinke wrote:
> I checked, and the reason is that D and C++ use a different ABI wrt. by-value passing of non-POD arguments. C++ indeed passes a reference to a caller-allocated rvalue, not just on Win64; that makes it trivial, as there are no moves across call boundaries. But your proposal may imply changing the D ABI accordingly.

That seems to be the case.

Assuming https://dlang.org/spec/abi.html is the ABI you refer to, there is very little in way of argument calling there:

https://dlang.org/spec/abi.html#function_calling_conventions

"
The extern (C) and extern (D) calling convention matches the C calling convention used by the supported C compiler on the host system. Except that the extern (D) calling convention for Windows x86 is described here.
"

So the current state is, in essence, that in C everything is PoD, and that's why that's also the case in D. Yes, something will need to change there.

Shachar
1 2
Next ›   Last »