On Mon, 06 May 2013 10:05:48 -0400, Andrei Alexandrescu
<[email protected]> wrote:
On 5/6/13 12:48 PM, Steven Schveighoffer wrote:
On Mon, 06 May 2013 06:43:38 -0700, Andrei Alexandrescu
<[email protected]> wrote:
I think we can technically make the overloading work while also
allowing binding rvalues to ref. But that wouldn't help any. Consider:
ref int min(ref int a, ref int b) { return b < a ? b : a; }
...
int x;
fun(min(x, 100));
Here the result of min may be bound to an lvalue or an rvalue
depending on a condition. In the latter case, combined with D's
propensity to destroy temporaries too early (immediately after
function calls), the behavior is silently undefined; the code may pass
unittests.
Wouldn't the new runtime check fix this?
Depends how you define "fix". It would be a possibly rare bounds check
violation on completely innocuous code.
By "completely innocuous" you mean valid? I don't think the above is
valid.
This is a known issue in C++. Allowing loose binding of rvalues to ref
not only inherits C++'s mistake, but also adds a fresh one.
I thought C++ would handle this kind of code. I remember being able to
use references to rvalues in ways that were unintuitive, but not
undefined.
template <class T> const T& min(const T& a, const T& b) {
return b < a ? b : a;
}
...
int x = ...;
auto & weird = min(x, 100);
Have a nice day :o).
It seems to compile and work for me, but I don't know what the point is,
since you are being mysterious :)
A long time ago I wrote a logging feature for C++ that returned an rvalue
(maybe it was an rvalue reference, it was a long time ago, and I don't
have the code anymore). That would collect log messages via the <<
operator, and then when the line was through, the destructor would output
that line to the logger. The logging object fetched would either be a
dummy no-output object, or a real logger, depending on the logging level
selected. If the logger was disabled, no message was constructed, making
it somewhat lazy (any expressions in the line would obviously be executed,
just like any standard logger). It worked without a hitch as long as we
used it. The rvalue stayed allocated and valid throughout the whole line,
even though it was passed into each << operation by reference.
-Steve