Binding rvalues to const ref in D
Atila Neves via Digitalmars-d
digitalmars-d at puremagic.com
Wed Oct 19 08:18:36 PDT 2016
New post since the the last one was already off-topic. Continued
from:
http://forum.dlang.org/post/nu7mv8$mqu$1@digitalmars.com
I get the feeling that people are talking past each other. I'm
going to give my view of the situation and everybody can correct
me if I'm wrong / throw tomatoes at me.code
On the one hand some people want rvalues to bind to const ref. I
can only assume that they want this because they want to pass
rvalues to a function efficiently - i.e. put a pointer in a
register. It might also be due to familiarity with C++ but I
speculate. If indeed I'm right, then I wonder if it's by instinct
or if it's been measured versus passing a struct by value. I just
wrote this:
struct Vector { float x, y, z; }
float silly(Vector v) { return v.x * 5; }
float test() {
Vector v;
return silly(Vector(1, 2, 3)) * 7;
}
Yes, it's a stupid example. But ldc2 -O3 gives me this for
`silly`:
movq rax,xmm0
movd xmm0,eax
mulss xmm0,DWORD PTR [rip+0x0]
ret
It's a bit longer than if I passed in a float directly:
mulss xmm0,DWORD PTR [rip+0x0]
ret
But... there's no copying or moving of the entire struct. C++
(also passing by value, I just hand-tranlated the code) is
similar but for some reason was better at optimising:
mulss xmm0,DWORD PTR [rip+0x0]
ret
nop
Again, no copying or moving. Which is what I expected. Granted,
real-life code might be complicated enough to make matters a lot
worse. I'm just wondering out loud how likely that is to happen
and how big of an impact on total performance that'll have. My
question is: do you _really_ need rvalues to bind to const ref
for performance? If not, what _do_ you need it for? Is it an
instinctive reaction against passing structs by value from C++98
days?
It's been mentioned that one might not get a say on how a
function is declared if calling, say, C++ from D. That's a fair
argument, and one I've not heard a solution for yet. Maybe allow
rvalues to bind to const ref in `extern(C++)`? I don't know, I'm
thinking out "loud".
On the other hand we have the "rvalues binding to const ref =>
rvalue references or other complicated mechanisms for figuring
out whether or not the const ref is an rvalue". This seems to
have not been explained correctly. I'm not blaming anyone, I just
tried yesterday and failed as well.
The situation is this: if one wants move semantics, one must know
when one can move. Because rvalues bind to const& in C++, you
never know whether the const& is an lvalue or rvalue. The
solution to this was rvalue references, which are refs that can
_only_ bind to rvalues. That way you know that the origin was an
rvalue an wahey, move semantics. They complicated the language
significantly. Did you know there's more than one kind of rvalue
in C++? Oh yes:
http://en.cppreference.com/w/cpp/language/value_category
Do we want that? I don't.
Summary:
* rvalues don't bind to const ref because if they did there'd be
ambiguity, and to solving that problem would make the language
more complicated.
* Knowing when passed-in parameters were actually rvalues turns
out to be something compilers want to do because performance.
* It'd be nice if D could call C++ functions that take const&
with rvalues
Tomato time?
Atila
More information about the Digitalmars-d
mailing list