On Mon, 14 Dec 2009 11:44:18 -0500, lws <[email protected]> wrote:
On 2009-12-14 07:01:47 -0800, dsimcha <[email protected]> said:
== Quote from lws ([email protected])'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