Magnus Lidbom said:
Magnus Lidbom said:
On Wed, 4 Feb 2004 07:06:06 -0600, "Daniel O'Connell [C# MVP]"
<snip>
Const correctness can only be guaranteed at compiletime, IMHO, if
you restrict calls to const methods only, on a const object. At runtime,
the CLR can check for const correctness via exceptions. The latter should
be enough for people who don't want other code to alter an object (tree)
which is returned by a method.
I think giving this choice like an OPTION STRICT kind of setting
for the compiler can satisfy every developer. True, you can't call
ToString() if you want to have compile time const-checking, however it
might be possible to let the compiler check if the code inside ToString()
is harmful to the object or not. (however this might be pretty complex)
As I was discussing with Magnus, it would be possible although it would
*need* to be done in some compiler agnostic manner.
<snip>
Seems I've failed to make myself clear. I never intended for the
mechanism to perform that type of code analysis. In fact, I don't feel
that would be appropriate as it would allow for contracts to be
violated. What I intended for the validation to check was that the
contract wasn't breached by code in languages that do not themselves
support const:
//const supporting assembly
class Foo
{
private int m_value;
public static const Foo GetInstance(){return new Foo();}
public int Value
{
//declare get const.
get const
{
return m_value;
}
set
{
m_value = value;
}
}
}
//non-supporting assembly. Oddly enough still C#.
class Bar
{
public void FooBar()
{
//Ok, even though myFoo is not declared const, since
//it's a non supporting language. A compiler switch could
//enable this behaviour in supporting languages to ease
//introduction of const correctness into existing code.
//Valid code in a supporting assembly would be:
//const myFoo = Foo.Getinstance();
Foo myFoo = Foo.Getinstance();
//OK.
Console.WriteLine(myFoo.Value);
//Validation fails at compile time.
myFoo.Value = 5;
}
}
Which is basically what I mean, *I think*, just simply that it would be an
external tool of some sort that does the analysis, instead of requiring the
compiler to do it
I Agree. Never meant to imply I didn't.
, that would have two effects, 1) it would be possible for
all compilers to behave correctly without adding alot of extra code and 2)
you could verify const correctness of code yourself. In an environment where
const doesn't exist in the first class it won't be possible to ensure 100%
that code is const correct without doing a full static analysis of the IL.
The above code, as I read it, makes it impossible for languages that don't
use const to use non-const methods on objects. If for no reason other than
it not being possible to apply metadata to an instance. Beyond that,
tracking references would be next to impossible. If that Foo was placed in a
hash table or array list, I very much doubt the compiler could keep track of
it...thinking about it now I am not sure that a static tool could either, so
this whole approach may not be feasible.
I'm think you're right, unfortunately.
Now, therun time on the other hand
probably could, but again not without some changes to the system. True.
This could be solved at some point, I've been working on a mechanism(still
playing with syntax) for attaching attributes to an instance of an object at
runtime.
Such a feature could, instead of making a const reference or
variable, be used to make a const instance, which would provide a much more
flexible approach to cross language issues than static tools and relying on
a const return attribute. It'd also make it harder to remove const, if you
deny untrusted code permission to modify the attribute set on an instance,
that code couldn't remove const and cause trouble. It would also allow the
runtime to easily detect if an instance is currently const and if you can
modify it.
I'm afraid I don't think that would do the trick. You'd need to be
able to apply it to references, instead of instances, since there are
quite often several references to the same instance, some const, some
not.
Well, it would be a different kind of const. Instead of const references it
would just give const instances. It is a different concept and I don't know
how well it would extend. It does have the benefit of strong const, keeping
it from being cast away, while you loose the ability to change const state
among references.
Anyway, how would you attach an attribute to an instance? The syntax
would be interesting, but even more so would be how the runtime would
do it. It would be have to be a completely separate mechanism from
what we call attributes in .Net at present I assume? Would it
necessitate changing the memory layout of classes? How about structs?
How would it play with interop and Sequential Layout? This is not
exactly simple :/
No, its not simple, which is where the fun is,
. Most of hte work I've
been doing is targeted at experimentation, both figuring out *how* to do
things and what situations I'm going to come up with where it won't work,
not nessecerily producing somethign that can work(although I am rather fond
of the security statements). Currently I'm thinking that such attributes
would be references stored somewhere in class memory, something like expando
properties but not. Adding a sort of a InstanceAttribute**, to use C++ style
declarations, to the header that points to a list(or linked list) of
attributes. As far as interop goes, I suppose it would be a Out of band
pointer, where only classes interested coming from a language capable of
dealing with such things would work. Perhaps post fixing attribute data into
the end of the class after its physical allocation would work, as long as
the remote client doesn't start moving data around. There is going to be
limitations no matter how it works.
My current syntax idea is to use keywords. Although I'm not particularly
fond of it, my current on paper is something akin to:
attach <attribute> to <targetObject>
or
object attributedObject = new object();
attach new InstanceAttribute() to attributedObject;
The problem is locating and dealing with attributes. There would have to be
a class that does attaching, detaching, and lookups, something in
System.Reflection, so it wouldn't be *nessecery* to have a syntax to do it,
but I am interested in the syntax.
Playing around with this in my head I can't come up with anything that
has a chance of working the way const should. It keeps coming back to
that, as far as I am aware, you can't attach information to references
without modifying the runtime representation of a reference. And
changing the runtime representation of references is not what I see in
the future for .Net.
It would be rather a powerful concept though. You could for instance
have the reference hold two pointers instead of one. One to the
instance data and one two the vtable. That would allow for all sorts
of runtime modifications of behaviour. The least powerful of which
would be to be able to implement runtime const checking.
I think it would be powerful. You wouldn't have to change the format of the
reference itself, but you *would* have to modify the table a reference
points to. Without finding the info specifically, one would assume that refs
work something like(pseudocode):
ref Reference;
RefData[] refTable;
RefData = refTable[ref];
public class RefData
{
void* vtable;
void* instanceData
Type* Type;
//and whatever else
}
simply for book keeping, Adding another field on there would be my immediate
solution, assuming it all works right(I havn't dug in deep enough to be
100%). Adding to that wouldn't be impossible if the runtime is well
written(pointer arithmetic is done centrally or by using global constants).
Internal class data layouts shouldn't matter and should be capable of
varying from version to version, they are, after all, internal structures
not meant to be consumed by anything but the runtime itself.
Granted, its unlikely anything I do will effect change in the spec, but it
does give me something to experiment with and room to consider things I
havn't before.
Currently I'm thinkg about security and control. What level of limitations
should be placed on access to such attributes, all read\privledged write?
all read\all write\privledged detach? Its something else I have to consider.
One could go so far as to enable instance attribute ACL's, specfying a type
and allowed actions
attach new InstanceAttributeAcl(typeof(MyClass),Actions.Attach |
Actions.Detach | Actions.Read) to myRestrictedInstance;
or extend the security system, it would all have to be considered. That'd be
another use, assuming instance attributes are properly access controlled,
they could be used to grant a given object security rights at runtime based
on various things instead of a type or publisher before runtime. Granted its
utility isn't massive, but it is interesting to me.
But, it keeps me from boredom(if this is what I do for fun, imagine bored,
).