What if D would require * for reference types?
Lars T. Kyllingstad
public at kyllingen.NOSPAMnet
Mon Jan 18 12:08:56 PST 2010
Steven Schveighoffer wrote:
> 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.
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
More information about the Digitalmars-d
mailing list