On Mon, 13 Jun 2011 01:06:43 -0400, Mehrdad <wfunct...@hotmail.com> wrote:

== Quote from Steven Schveighoffer (schvei...@yahoo.com)'s article
On Sun, 12 Jun 2011 23:58:01 -0400, Mehrdad <wfunct...@hotmail.com> wrote:
I'll see if it's in my sent mail...
OK, I found it, it was actually the same logic but applied to shared
objects.  But Walter convinced me that the issues are the same (at least
for this problem).
Consider this type:
struct S
{
    Object o;
}
now, we have these two variables:
const(S) s;
const(Object) o;
finally, the issue:
void kryptonite(ref const(Object) o)
{
    o = new Object();
}
kryptonite(o); // fine
kryptonite(s.o);// oops!
The problem is, there isn't a way to distinguish a tail-const object
reference from a fully const object reference, yet both types can exist.
If you want to pass a reference to such a reference, then you run into
sticky issues like this one.
I understand that you want final to mean "head const", but final is a
storage class, not a type modifier -- it cannot be used as part of the
type info.
-Steve

Hm... that's a reason, but it seems like we can get around it relatively easily.

It seems like it could be solved by making it so that const(S) also makes the fields of S final. That way,
you could no longer do `kryptonite(s.o)` because it's final.

You could then say "final ref const Object o" to allow for passing that field, because that would mean the
callee cannot modify o.


Wouldn't that work?

No. final is not a type constructor, so it does not get carried around with the type.

final int i;

assert(typeof(i) == int); // after the declaration, the storage class is gone from the type!

int * ip = &i;

*ip = 4; // can't be forbidden.

final can only apply to the storage of the variable, and I'm not actually sure the above is valid in today's D2. I think it's only a storage class in D1. In D2, I think it's only use is to declare a function as not-virtual.

-Steve

Reply via email to