[bitc-dev] BitC 0.20: Immutable, const, and readonly
Jonathan S. Shapiro
shap at eros-os.org
Wed Mar 10 16:00:14 PST 2010
On Wed, Mar 10, 2010 at 3:39 PM, Michal Suchanek <hramrach at centrum.cz> wrote:
> On 11 March 2010 00:14, Jonathan S. Shapiro <shap at eros-os.org> wrote:
>> That is: the type of the assignment operator is:
>> Assign(mutable S by reference, shallow-readonly S by reference)
> Yes, that gives a more precise description of the assignment operator.
> I don't see where this description is actually useful...
Turns out that it's necessary for a complete type system. If the input
to assignment is declared as mutable, then you can't pass read-only
things. Conversely, if it is deep readonly, you can't assign things
that contain references to mutable state.
The original BitC type system didn't have this, and we were forced to
add it to make the type algebra work out at assignment and parameter
> but it certainly more precise than
> Assign(mutable S by reference, mutable S by reference)
Which is incorrect.
> and somewhat easier to express (and still more precise) than
> Assign(mutable S by reference, mutable unless simple S by reference)
Which is also incorrect.
>> Serious answer: the ability to clearly express the fact that we are
>> constrained by a deficient contract, and must be aware of its
> And the serious question is: do we care in the cases when the contract
> is deficient?
Only if you want to run code in the real world.
The more interesting question, to my mind, is whether those other
languages actually honor their own contract. C, as you point out,
considers 'const' to be an advisory notion. CLR has a (somewhat
broken) read-only field notion, but doesn't have a notion of
permissions on references. This raises the question: do we actually
have to change anything in order to be able to express the true
contracts of types in those languages?
Pragmatically, however, read-only contracts at procedure parameters
has a significant impact on register reload. The question then
becomes: how often will it turn out that deep readonly sufficed, and
what are the marginal cases covered by shallow read-only?
My hunch is that we still need shallow read-only as an internal matter
within the type inference engine. As a trivial example, all cases of
object reference passing are shallow read-only but generally not deep
> There are clearly two deficiencies here, const structs containing
> pointers or similar const backdoors and the ability to cast const data
> to non-const in C.
> The former can be easily detected and the latter can be prevented by
> compiler flags but can be still broken by inline assembly, external
> libraries, and whatnot. C is simply not safe.
Yes. I'm actually not focused on C here so much as on CLR and CTS.
> In some cases (C++ at least) there is a distinction between a
> reference which names a particular object...
It is unfortunate and confusing that the C++ terminology differs from
all other object-based language terminology before and after. C++
means something that is most similar to "by-reference" and is a
conservative approximation to a non-escape contract. Regrettably it is
not true that a C++ reference names a particular object. A C++
reference can be null. This is assumed not to be possible, but is true
in practice and is not guarded against.
More information about the bitc-dev