What if D would require * for reference types?
Steven Schveighoffer
schveiguy at yahoo.com
Mon Jan 18 11:48:50 PST 2010
On Mon, 18 Jan 2010 13:35:01 -0500, Bill Baxter <wbaxter at 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.
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.
-Steve
More information about the Digitalmars-d
mailing list