const again

Steven Schveighoffer schveiguy at yahoo.com
Thu Dec 6 16:30:15 PST 2007


"Walter Bright" wrote
> Janice Caron wrote:
>> I understand the problem. Have you considered the possible solution
>> which has been suggested on this group - a special syntax for classes
>> having mutable refs to constant data? Under that suggestion, the above
>> code would become:
>>
>>         class C { }
>>         const(C)&[] a;
>>         a[3] = new C();  // OK
>>
>> It's the ampersand that makes it OK. It tells you that the reference
>> is not constified.
>>
>> I think that would work, in exactly the same way that
>>
>>         struct S { }
>>         struct(S)*[] a;
>>         a[3] = new S();  // OK
>>
>> works.
>
> There are a couple problems with it, the worst of which is its impact on 
> generic code:
> const(T)[]
> Would you put the & there or not? What would & mean if one wrote:
> struct S { C c; }
> const(S)&[] a;
> ?

What happens if you have this?
const(T)*[]

If T is a struct, then it's fine, but if it's a class, then what?  To me the 
situation is just as bad.

This whole problem stems from the fact that a struct declaration is a value 
type and a class declaration is a reference type, but they look the same. 
You are never going to have a consistent syntax for generic const code 
because you don't have a consistent syntax for normal declarations.

I see one good solution.  A pointer/reference declarator that acts the same 
for both structs and classes.

class C {}
struct S {}

C x; // a reference to a class
S x; // a struct
C& x; // a reference to a class (identical to C x)
S& x; // a reference to a struct (identical to S * x)

S& x = new S; // heap allocated struct
C& x = new C; // heap allocated class

const(C) x; // a const reference to a const C
const C x; // identical to const(C)
const(C)& x; // a mutable reference to a const C
const(C)[] x; // an array of const references to const C instances
const(C)&[] x; // an array of mutable references to const C instances

const(S) x; // a const S.  Cannot set x or x.member
const S x; // identical to const(S)
const(S)[] x; // an array of const S types
const(S)*[] x; // an array of mutable references to const S types
const(S)&[] x; // an array of mutable references to const S types (identical 
to const(S)*[])

you need generic tail-const code? use const(T)&

you need generic fully-const code? use const(T)

or use something else instead of &, I don't care.  It just seems like this 
notion that I can now have tail-const structs, but not tail-const classes is 
just as bad, if not worse, than the original problem.

> One principle we try to adhere to is that it should make sense to be able 
> to wrap any type with a struct, and have it be possible for that struct to 
> behave as if it were that member type.

const (X)* m;

Please tell me how you will replace m with a 'smart' pointer type that is 
mutable, but the pointer contents are not.  Without using a template. 
Because using a Template, I can do it with my regime also :)

> And finally, this suggests that & means "tail-const". Tail-const has that 
> severe problem that there is no such thing as a tail-const member function 
> (i.e. a member function that can modify the fields of the object, but not 
> anything those fields refer to).

Huh?  I thought tail-const was that you could change the reference but not 
the members? i.e. const(S)* x, I can change x but not x.member?

-Steve 





More information about the Digitalmars-d mailing list