DMD 0.177 release

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Fri Dec 15 10:40:22 PST 2006


Kevin Bealer wrote:
> == Quote from Andrei Alexandrescu (See Website For Email)
> (SeeWebsiteForEmail at erdani.org)'s article
>> ++s[a]; // possible through a compiler hack
>> ++s(a, b); // impossible
> 
> I missed this possibility.  In order to solve just this next step { ++s(a, b); },
> it seems like D would need something that copies like a pointer to either a struct
> or class reference, but automatically turns into (or acts like) a regular
> reference or LValue when something like ++ is applied.  This means something in
> between a pointer and an LValue.

I think it's an lvalue all right. Inside the compiler it's very clear
what's an lvalue and what's not. Think of this:

int x;

Wherever you use x, even if you pass it to functions etc., the compiler
entirely knows it's an lvalue. If, on the other hand, you use (x + 1),
all of a sudden the compiler understands that's an rvalue, and
accordingly won't let you e.g. pass it as an out or inout parameter.

I was quite worried last night about this issue, but now I think I
realize that returning from a function is about the only (I hope!) case
in which the lvalue yes/no information about a value is lost. That is,
you can't today write a function ident() that is totally transparent -
i.e., can be added around any expression with no effect whatsoever:

template ident(T) {
   T ident(T rvalue) { // works
     return rvalue;
   }
   T ident(inout T lvalue) { // loss of information
     return lvalue;
   }
}

By the way, ident() is a good function to check a language's quality. If
it can't be implemented at all or efficiently, then the language is not
ideal. Most languages can implement ident() but not efficiently. C++
came close to implementing it properly, but all the confusion between
rvalues and const references made implementation exceedingly difficult
(to add insult to injury, built-in rvalues are treated differently than
user-defined rvalues). Current D cannot implement ident at all. I also
wonder whether overloading on inout is possible. I think not, and if
not, that is a good urgent item to put on the list. The code that should
compile and execute correctly is:

template ident(T) {
   T ident(T rvalue) { // works
     return rvalue;
   }
   inout T ident(inout T lvalue) { // works
     return lvalue;
   }
}

> I kind of hate to say it, but given all this, how far am I from describing a C++
> "&" type?   Is there anything the C++ type does that isn't in the above list?
> (Other than the new proposal for '& &' references I guess, which seems unnecessary
> for D.)

There are a few differences that make all the difference :o). One is
that C++ is too eager to convert rvalues to const &, which has caused an
unbounded amount of harm. Second, in C++, T& is a type indeed, but it's
a half-life type, a pariah. So it would be probably wise to do the
entire lvalue/rvalue distinction without making references into types.
For example, outside function declarations, there should be no other
place where inout can be used.


Andrei



More information about the Digitalmars-d-announce mailing list