The liabilities of binding rvalues to ref
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sat May 4 22:49:42 PDT 2013
Here are the issues that need to be addressed by any solution
reconciling rvalues and passing into functions. This post is not arguing
for any particular solution or approach, but lays down the issues that
any approach must be judged by.
1. The LRL (Lvalue-Rvalue-Lvalue) problem.
This has been long mentioned as an argument in defining C++'s
references. The crux of the issue is that caller code passes an lvalue,
and the callee code receives an lvalue, but in the middle there's an
rvalue created by an implicit conversion. Consider:
void fix(ref double x) { if (isnan(x)) x = 0; }
...
float a;
...
fix(a);
If rvalues bind indiscriminately to ref, then the call is legal because
of the implicit conversion float->double.
A possible solution is to disallow binding if the initial value bound is
an lvalue.
2. Code evolution.
Jonathan mentioned this too. The problem here is that as code evolves,
meaningful code doing real work becomes silently useless code that
patently does nothing. Consider:
class Collection(T) {
ref T opIndex(size_t i) { ... }
...
}
void fix(ref double x) { if (isnan(x)) x = 0; }
void fixAll(Collection!double c) {
foreach (i; 0 .. c.length) {
fix(c[i]);
}
}
As design evolves, Collection's opIndex may change to return a T instead
of ref T (e.g. certain implementations of sparse vectors). When that
happens, the caller code will continue to compile and run. However, it
won't do anything interesting: fix will be always called against a
temporary plucked from the collection.
Changing return types from ref T to T or back and expecting no ill
effects (aside from fixing compile-time errors) is a frequent operation
in C++ projects I'm involved in. Doing worse than that would be arguably
a language design regression.
Note that in function call chains fun(gun(hun())), which are common
(written as fun.gun.hun etc) in the increasingly popular pipeline-style
of defining processing, one function changing return style poisons the
well for everybody down the pipeline. That may lead to pipelines that
have only partial effect.
=======
There may be other important patterns to address at the core, please
chime in. I consider (1) above easy to tackle, which leaves us with at
least (2). My opinion is that any proposal for binding rvalues to ref
must offer a compelling story about these patterns.
Andrei
More information about the Digitalmars-d
mailing list