Steven Schveighoffer wrote:
On Mon, 18 Jan 2010 13:35:01 -0500, Bill Baxter <wbax...@gmail.com> wrote:
I think one can argue it would be better for pointer arithmetic to
require a more in-your-face notation, since pointer arithmetic isn't
usually needed and won't even be allowed in SafeD.
It isn't really standard arithmetic to begin with, since foo++
(pointer meaning) is more like foo += sizeof(Foo);
Also adding pointers together is not allowed. These two things, I
think, form the basis of a decent justification for making pointer
arithmetic syntactically distinct from regular arithmetic.
So, for instance, you could require distinct operators like *++, *+,
*- for pointer manipulations.
Maybe we're on to another big mistake of C here -- conflation of
pointers with numbers. Or at least a corollary to the mistake of
conflating of arrays with pointers.
The question that then comes up is can you do overloading of those new
operators? If you want to make something that is "pointer-like", then
it would be necessary to do so. But probably only value-types should
be allowed to act in a pointer-like manner. So you could only
overload pointer arithmetic operators in a struct. But I'm not sure
there's a use case for even that.
pointers are essentially unrestricted arrays also. So you'd also have
to disallow ptr[x]. Basically any operation that normally gets
forwarded to a class reference but would be intercepted by the pointer
has to be given a new syntax.
I'm wondering, is there an issue with signifying rebindable references
like C++'s references, i.e. C& ? (question mark separated for clarity)
C& classref = new C();
C& classref2 = classref; // does not create a new instance, but just
copies the reference
S& structref = new S(); // struct reference!
S& structref2 = structref; // structref2 and structref bind to same data.
S structref3 = *structref2; // must dereference to access value
*classref2 = *classref; // Error! illegal to derference class references.
S& structref4 = &structref3; // pointer implicitly casts to reference.
C classref3; // illegal
const(C)& constref; // tail-const class reference!
ref can still be used as a storage class, meaning you can use it as if
it were a value type. But the & types will be explicitly a reference
type, meaning:
foo(ref int x; int& y)
{
int z;
assert(is(typeof(z) == typeof(x));
assert(is(typeof(y) != typeof(x) && typeof(y) != typeof(z));
y = z; // illegal;
*y = z; // correct;
y = &z; // correct, but unsafe.
y = x; // also illegal
y = &x; // ok (possibly unsafe).
y += 5; // compiler error or equivalent to *y += 5 ?
}
basically, & is a pointer that only supports the operators = * and
'is'. I think conversion from a reference to a pointer should be
available via a cast, but I'm not sure whether the compiler should allow
class pointers. My gut feeling is no.
Isn't this already possible?
class Foo { }
Foo foo = new Foo;
Foo* ptr = cast(Foo*) foo;
// ptr is not a pointer to the reference.
assert (ptr != &foo);
Are there any syntax ambiguities here? & is also a binary op, but then
again, so is *. Will there be an issue with && ? I mean, because the
references are rebindable, you should be able to have a reference to a
reference.
Also, struct references in this way will be usable in safe D, enabling
heap struct data!
The more I think about it, the more I like having an explicit reference
denotation for classes, with the compiler enforcing that you simply
can't use class data as a value type. This basically makes all the
tail-X syntax just work, and still retains the benefits of classes being
reference-only types. The tail shared problem is a really crappy issue,
worse than tail-const.
I like it too. :) But I'm not sure we should use the & symbol:
Foo& foo = new Foo; // & denotes a reference
Bar* bar = &barValue; // & returns a pointer
Yes, C++ does it, but it's still ugly.
-Lars