[phobos] [D-Programming-Language/phobos] 601c75: Improve parsing error handling

Jonathan M Davis jmdavisProg at gmx.com
Mon Sep 5 02:27:46 PDT 2011


On Monday, September 05, 2011 11:20:57 Don Clugston wrote:
> On 5 September 2011 10:15, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> > On Monday, September 05, 2011 09:46:02 Don Clugston wrote:
> >> On 5 September 2011 09:35, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> >> > On Monday, September 05, 2011 00:27:05 Walter Bright wrote:
> >> >> On 9/4/2011 11:41 PM, Jonathan M Davis wrote:
> >> >> > It still baffles me why anything other than a variable would
> >> >> > be an
> >> >> > lvalue
> >> >> 
> >> >> *p is also an lvalue.
> >> > 
> >> > Good point, but that's essentially the same as setting the return
> >> > value of a function that returns by ref, which essentially is a
> >> > variable. But I guess that it does come down to an address more
> >> > than a variable. What I really don't get is the temporaries such
> >> > as when you construct a struct in place - e.g. S(1) - functioning
> >> > as lvalues. The result is that if you have an opEquals which
> >> > takes const ref like it's supposed to (or any function which
> >> > takes a const ref, but opEquals is a good example), then you can
> >> > pass it S(1) but not a the result of a function that returns
> >> > S(1).
> >> > 
> >> > struct S
> >> > {
> >> >    bool opEquals(const ref S rhs)
> >> >    {
> >> >        return val == rhs.val;
> >> >    }
> >> > 
> >> >    int val;
> >> > }
> >> > 
> >> > S func()
> >> > {
> >> >    return S(1);
> >> > }
> >> > 
> >> > void main()
> >> > {
> >> >    auto s = S(1);
> >> >    assert(s == S(1)); //compiles
> >> >    assert(s == func()); //doesn't compile
> >> > }
> >> > 
> >> > Obviously, this is a complicated issue, but the situation above is
> >> > downright confusing to many people (e.g.
> >> > http://stackoverflow.com/questions/6986175/const-ref-and-rvalue-in
> >> > -d ). It seems completely inconsistent. Even if C++ treats stuff
> >> > as lvalues or not in exactly the same way in D, it's not an issue
> >> > in the same way in C++, since const S& will take a temporary in
> >> > C++, whereas const ref S won't take a temporary in D.
> >> 
> >> It's not merely confusing. AFAIK there is no possible signature of
> >> opEquals which actually works.
> >> I think two different issues may be being conflated here, though.
> >> I think there's more of a problem with the semantics of 'const ref'
> >> and 'auto ref', than with literals being lvalues.
> > 
> > Well, at present you can declare a second version of opEquals which
> > takes its argument by value, and it works.
> 
> I've never been able to get that to work. Although you can get those
> two to work, it fails in other cases. Eg, as in the code below.
> Have you been able to do this successfully?
> 
> struct S
> {
>    bool opEquals(const ref S rhs) const
>    {
>        return val == rhs.val;
>    }
>    bool opEquals(S rhs) const
>    {
>        return val == rhs.val;
>    }
> 
>    int val;
> }
> 
> S func()
> {
>    return S(1);
> }
> 
> void main()
> {
>    auto s = S(1);
>    assert(s == S(1)); //compiles, const ref
>    assert(s == func());  // compiles, value
>    immutable s2 = S(1);
>    assert(s==s2); // fails, ambiguous
> }

Probably not. I don't think that I've tried though. I'm not sure how often 
I've used immutable structs in a context that ended up using an equality 
check.

Regardless, opEquals obviously needs to be sorted out. You shouldn't need two 
definitions like that to get it to work even if they did work in all cases.

- Jonathan M Davis


More information about the phobos mailing list