rvalues -> ref (yup... again!)
Rubn
where at is.this
Sat Mar 24 22:59:06 UTC 2018
On Saturday, 24 March 2018 at 11:57:25 UTC, John Colvin wrote:
> I understand what you want, but I'm struggling to understand
> why it's such a huge deal.
>
> The reason you want to pass by reference is for performance, to
> avoid copying the data at the call boundary.
It's pretty simple:
float foo() { ... }
ref float bar() { ... }
void someFunc(ref float);
someFunc(bar()); // ok
float temp = foo();
someFunc(temp); // Have to create a temporary anyways for the
function to work
someFunc(foo()); // Compile error, need to use the hideous code
above
So there really isn't any performance penalty cause if you want
to call that function you are going to have to create a temporary
variable anyways, but now you can't just call the function in one
line. It requires multiple lines and a temporary variable name.
This becomes especially horrible for math libraries:
void someFunc(ref Vector3) { ... }
someFunc(a + b); // Can't do this
Vector3 temp = a + b;
someFunc(temp); // Have to do this
So there's no performance penalty for what he is requesting, but
allows for a cleaner syntax to do the exact same thing.
> So there are 2 cases: an lvalue needs to be passed, or an
> rvalue needs to be passed.
>
> 1. The address of the lvalue is passed.
>
> 2. The rvalue is copied to a local, then the address of that
> local is passed.
>
> So in the rvalue case, you're not getting the performance
> benefit of passing by reference, because you have to copy to a
> local anyway.
>
> What I would do in D currently to get the same performance and
> API:
>
> void foo(float[32] v) { foo(v); }
> void foo(ref float[32] v) { ... }
>
> or
>
> void foo()(auto ref float[32] v) { ... }
>
> What is so totally unacceptable about those solutions? I
> personally like the second because it scales better to multiple
> parameters. I know you have said it's not relevant and annoying
> that people bring up auto ref, but I dont' get how or why. It's
> exactly D's solution to the problem.
It doesn't scale better, that's part of the problem:
void foo()(auto ref MyType1, auto ref MyType2, auto ref MyType3,
auto ref MyType4) { ... }
The above has the possibility of generating 16 different
functions that basically all do the exact same thing. It creates
excessive bloat, and now what if you want to take the address of
the function? You can't cause you have to choose between one of
the 16 variants.
This is template bloat at it's finest, except it isn't even doing
anything useful. I can only imagine telling someone they have to
code gen 16 identical functions just to be able to call a
function without having to create useless temporary variables in
the scope a function is being called in.
More information about the Digitalmars-d
mailing list