On Thursday, 17 May 2018 at 12:36:29 UTC, Shachar Shemesh wrote:
Again, as far as I know, structs are not copied when passed as arguments. They are allocated on the caller's stack and a reference is passed to the callee. If that's the case, no move (of any kind) is done.


That's the exception to the rule (LDC's `ExplicitByvalRewrite`), and true for structs > 64 bit on Win64 (and some more structs) and something similar for AArch64. No other ABIs supported by LDC pass a low-level pointer to a caller-allocated copy for high-level pass-argument-by-value semantics; the argument is normally moved to the function parameter (in the callEE parameters stack).

```
struct S
{
    size_t a, b;
    this(this) {} // no POD anymore
}

void foo(S param);

void bar()
{
// allocate a temporary on the caller's stack and move it to the callee
    foo(S(1, 2));

    S lvalue;
// copy lvalue to a temporary on the caller's stack (incl. postblit call)
    // and then move that temporary to the callee
    foo(lvalue);

    import std.algorithm.mutation : move;
    // move move()-rvalue-result to the callee
    foo(move(lvalue));
}
```

'Move to callee' for most ABIs meaning a bitcopy/blit to the callee's memory parameters stack, for LDC via LLVM `byval` attribute.

See IR for https://run.dlang.io/is/1JIsk7.

Reply via email to