On Tuesday, 23 June 2015 at 09:57:26 UTC, Marc Schütz wrote:
On Monday, 22 June 2015 at 19:05:28 UTC, kinke wrote:
[...]
To clarify: What I meant by my comment was that const-ness should not be a precondition for allowing rvalue refs. Mutable rvalue refs are fine.

I know and see it the same way.

As I have already pointed out in another thread, I'd go one step further and propose an extremely convenient `in T` for this very common use case:

* The argument is passed by value (`const T`) if the compiler assumes moving/copying is more efficient than passing a reference (with its indirection on the callee side) for the particular target environment (hardware, ABI), e.g., for plain-old-datatypes T fitting into 1-2 registers, and Object references obviously. * Otherwise, the argument is passed by-ref (`in ref T`). As `in T` doesn't mention any ref at all, it's clear that the hidden reference cannot escape.

Theoretically, `immutable ref` by itself would already allow these semantics (without the `scope` that `in` implies). Because (disregarding identity/addresses) for an immutable object there is no observable difference between pass-by-value and pass-by-reference. The same is not always true for `const ref`, whenever aliasing is possible:

    void foo(const ref int a, ref int b) {
        int x = a;
        b++;
assert(x == a); // can fail if both refer to the same variable
        // similar with global variables
    }

To guarantee this from the caller's POV, the callee must be pure and the parameters must be known not to alias each other.

This is obviously true. Rvalues aren't affected as they cannot alias another parameter by definition. Lvalues are if passed by ref and the same instance is accessible by mutable ref from another parameter or global. But as shown by your example, that danger is always there. The proposed `in` semantics make it less obvious, that's true, but I still think it'd be worth it, as these aliasing bugs are a pain to track down, but in my experience extremely rare.

Reply via email to