opEquals(const ref yadaYada)
Steven Schveighoffer
schveiguy at yahoo.com
Tue Dec 15 07:43:45 PST 2009
On Mon, 14 Dec 2009 11:44:18 -0500, lws <invalid at email.com> wrote:
> On 2009-12-14 07:01:47 -0800, dsimcha <dsimcha at yahoo.com> said:
>
>> == Quote from lws (invalid at email.com)'s article
>>> I don't know if I believe this is necesarrily bad. It's revealing some
>>> bad coding on your part.
>>> You shouldn't be doing opEquals with an rvalue of a class. Make
>>> getFoo return a reference.
>>> ref Foo getFoo() {} fixes the problem and avoids value-copying for no
>>> reason to an rvalue that's going to get garbage collected.
>> 1. This was in DFL's code, not stuff I wrote.
>> 2. It was a small struct that was cheap to copy, not a class.
>> 3. At any rate, the inconsistency with builtins is inexcusable.
>
> 1. Well, stuff like this is good warning to whomever about the code.
> Since D is a imperative language, it should at least give you a warning
> when you're doing something really inefficient that has a boilerplate
> way of accomplishing it that is much faster.
It's not faster, it's slower. Passing a reference to an integer or
smaller value type is not as efficient passing the value type itself.
> 2. That's odd. structs DO have stack scope in D. Right? It
> shouldn't even warn in that case. IMHO.
The issue is that the compiler is incorrectly assuming that it *must* use
a const ref form of opEquals for a member when composing an opEquals
function for a struct that doesn't provide one. To this end, it always
ensures any overload set of opEquals has a const ref form. The premise
that const ref is always required is false in some cases, and this is the
bug.
> 3. For classes, it is consistent with the whole point of the new const
> stuff and the GC, and the fact that they are heap objects by
> definition. Classes have always been treated "differently." And I
> think it's good. Walter has enabled a lot of expressiveness with the
> syntax in D when compared to C++, and it allows nice warnings when
> you're doing things you probably shouldn't.
Classes should be allowed to be passed as const only, no ref. Passing a
reference to a class makes no sense since they are references already
(Even scoped class variables are references).
In fact, const ref makes absolutely no sense for a class, ever.
> Unfortunately, this isn't an error.... Maybe for some reason you
> REALLY want to be copying around structs and classes.
It is an error, not a warning.
The following opEquals functions should always compile:
struct S1
{
int x;
bool opEquals(S1 s) const { return true; }
}
struct S2
{
int *x;
bool opEquals(const S2 s) const { return true; }
}
The following should not necessarily compile:
struct Sbad
{
int *x;
bool opEquals(Sbad s) const { return true; }
}
-Steve
More information about the Digitalmars-d
mailing list