Casting const/invariant

Daniel919 Daniel919 at web.de
Wed Jan 2 16:40:48 PST 2008


> Right now, the docs say "[When casting data to invariant] it is up to the programmer to ensure that no other mutable references to the same data exist. "
When creating a new invariant struct/class, the compiler can always 
infer a cast(invariant).
invariant clFoo foo = /*cast(invariant)*/ new clFoo();

> Const is useful for interface guarantees, but does not allow the compiler to optimize code like it can with invariant data.  Unlike const, the compiler will be unwilling to (silently) cast data to invariant.  For invariant data to be useful, I think there needs to be a way for casting to be safe.
Correct, const is only logical, not physical, as it is now and therefore 
has to be treated like mutable.

> I think the key is adding a concept of exclusive write access to data.  For the sake of this post, I'll call data with exclusive write access "exclusive" and those that don't have it "shared".  Just to confuse everyone, I'll use "readonly" instead of const in my discussion...
I recommend the use of readonly instead of const. See my post 
"const=readonly invariant=const".

> Note that with this notation,
>   invariant = exclusive readonly
>   const = shared readonly
> 
> shared data gives behavior exactly like everyone currently expects.  You never know who has a mutable reference to the data, and the compiler gives no guarantees to that fact.
> 
> exclusive data can be implicitly cast to scope invariant for function calls.  This would allow a function with const parameter signature to use a version optimized for invariant access.
> 
> I would suggest that member/global variables default to shared access and local variables (in functions) default to exclusive access.  Using the variables as "in" parameters or "scope ref" parameters would require no modification.  Using them inside delegates or passing to non-scope "ref" parameters would require the data be shared.
> 
> Function return types and out parameters to functions are the stickiest part.  By default, they'd have to be shared access, but for this scheme to really be worthwhile, some framework for specifying when these outputs can be used as exclusive access (AKA the function leaves no mutable references in any other locations)
> 
> Thoughts?
In my ideas, const is the keyword that is mostly used. Therefore the 
compiler would not have to silently try to convert
"const int x = 1;" to what it actually means: "invariant int x = 1;"

readonly would mean what you call "shared readonly"
and const what you call "exclusive readonly"

readonly data in general has to be treated like mutable data
For optimization the compiler might generate two versions (of a function):
one for the case that the data is mutable
another for the case that the data is const

void foo(readonly Foo foo) { return foo.x; }
generates two versions, that are overloadable
void foo(/*mutable*/ Foo foo) { return foo.x; }
void foo(const Foo foo) { return foo.x; } //can be optimized



More information about the Digitalmars-d mailing list