[dmd-beta] D 2.059 beta 4

Andrei Alexandrescu andrei at erdani.com
Tue Apr 10 00:06:13 PDT 2012


On 4/10/12 1:28 AM, Walter Bright wrote:
> Let's say the compiler auto-generates the following:
>
> void foo(T t) { foo(t); }
>
> in case it sees:
>
> void foo(ref T t) { ... }
>
> I don't think that's a solution at all. It's just a roundabout way for
> the compiler to generate a temporary anyway. Nothing has been gained.

I agree.

To answer the question about why rvalue -> const& has been a mistake in 
C++: the history is, C++ had trouble with defining copy constructors. 
The simple idea would be

T(T source);

but this didn't quite work because of the infinite regression:

T a;
T b(a); // recurses forever

Going with

T(T& source);

would make this code nonworking:

T fun();
T a(fun());

because C++ does not allow rvalue to modifiable conversion on 
correctness grounds.

Now, the solution C++ chose to solve this was to make const& a universal 
sink for rvalues, modifiable lvalues, and const lvalues altogether, and 
the copy constructor became:

T(const T&);

That solves the infinite regression nicely but at the cost of 
introducing an unnatural conversion rule that ultimately disabled this code:

void fun(T);
void fun(T&);
void fun(const T&);

The mechanisms through which these overloads were deemed illegal are 
complex and non-obvious; practically it was a sheer consequence of the 
fact that overloading rules were already difficult and nobody figured 
that the rvalue overload was necessary, so it fell by the wayside.

(We've seen similar subtle issues arising with hashtables - Teoh tried 
to put hashes in a library and hit a maze of subtle special cases that 
work for the built-in type but not for library one simply because no 
attention was paid to that.)

So now C++98 got standardized, and before long it was clear that 
unnecessary copies were a large liability. It was, however, impossible 
to introduce a new overload rule without breaking some code that counted 
on it. That prompted the entire rvalue references work, which is a maze 
of rules and special cases designed to navigate the wreck created by the 
rvalue -> const& trivial conversion.


Andrei


More information about the dmd-beta mailing list