Clarifying 'const' terminology

Bruno Medeiros brunodomedeirosATgmail at SPAM.com
Sat Jul 8 12:45:50 PDT 2006


Derek Parnell wrote:
> I'm not from a C++/C#/Java background, so please excuse my lack of 
> understanding about the meaning that is being applied to the term 
> 'const' in these recent discussions.
> 

I think many times people talked a bit vaguely with their meaning of const.

> To me, there seems to be two things being talked about.
> 
> (a) Data, which once initialized, is not to be modified for the run-time 
> life of the application.
> 
> (b) Data, which once passed to some function, is not to be modified for 
> the run-time life of that function.
> 
> Walter's proposed refinement of the 'in' keyword does nothing for type 
> (a), and only limited support for type (b), in that it protects data 
> from the called function but not from functions that that subsequently 
> calls. It is only protection for one level deep. And the only data 
> protected is class objects and not other reference types.
> 
> Is there any other types (or subtypes) of 'const' meanings being 
> discussed or considered?
> 
> For example, are we distinguishing between compile-time protection and 
> run-time protection?
> 

'const', in a general sense, is a mechanism to specify whether a 
variable/data/object can or can not modified, and enforce that contract 
(at compile time). 'const' is usually in the sense of (b), that is, some 
parts of code may modify the data, while others can only read it (thus 
it is used for ownership management). That's the case for C++.
Enforcing the contract means you cannot assign a const variable to a 
non-const one, or similarly, pass a const variable to a function that 
expects a non-const argument. The only way to subvert this is with a 
cast (which should be the only way to subvert anything).

There are some variations in const semantics. In C++, const is a 
type-modifier, meaning that const can be applied to each type element, 
and not the "variable as whole". Best to give an example. In C++ you can 
have:
   const int * iptr = ...;
   int const * iptr = ...;
   const int const * iptr = ...;
each with different meanings:

   const int * iptr = ...;
   // cannot modify the pointed int, can modify the pointer

   int const * iptr = ...;
   // can modify the pointed int, cannot modify the pointer (the pointer 
is const)

   const int const * iptr = ...;
   // Cannot modify the pointed int, nor cannot modify the pointer

In this usual meaning (C++), there are no guarantees that the data will 
not actually change (by someone else for example) or that it is a 
compile constant. (That is why I say the use of this notion of const is 
for ownership management).

In D, 'const' is not a type modifier but what Walter calls a "storage 
modifier" (or storage attribute), but I think "variable modifier" is 
perhaps a better term. D's const is applied not to each of many possible 
type elements, but to the whole variable, like private or other 
protection attributes (and as such there can be only one const per 
declaration). D's const also has two different meanings (a bad thing 
IMO), and they're both different from C++'s:

* const var declaration with an initializer:
-> the value of the variable is a compile time constant. The variable 
has no storage, it becomes an alias for it's initializer literal. (and 
has such one can't take the address of it)

* const var declaration without an initializer:
-> the var can be initialized in constructors only, and on all other 
places it's value is read-only. The variable has normal storage. This is 
what is (much more properly) called 'final' in other languages.

There are some more possible variations. There can be a const that has 
the same meaning as C++'s (you cannot change the var), but which is a 
variable modifier instead of a type modifier. But in this case there is 
a prominent issue of whether the read-only/immutability property is 
transitive or not. For example (calling this behavior 'readonly'):
   readonly int **ptr;
Can one change *ptr and **ptr ? Or just ptr?

And there are quite some more issues to consider when implementing a 
'const' mechanism such as this one. (see below)

> My requirements for 'const' are almost covered by Walter's new proposal. 
> I'm a quite concerned that if I tell Foo() that it can't change 
> something, that Foo() can still tell Bar() to disregard my request and 
> tell Bar() that it's okay to change it anyway.
> 
> I think that apart from array references, type (a) const can be acheived 
> through using private members and public properties. I'm not sure how we 
> can fully implement (a) with current D semantics.
> 
> --Derek Parnell
> Melbourne, Australia

I'm assuming that in that that last "(a)" you meant "(b)".
Implementing a mechanism such as this is actually quite complex (in 
terms of design itself) because of several special cases which need more 
language constructs. It's not just adding the "immutable" keyword as 
some people seem to think.
To know what I'm talking about exactly one should read this quite 
informative paper:
http://pag.csail.mit.edu/pubs/ref-immutability-oopsla2005-abstract.html
I haven't read it all yet, but I plan to do so soon, since everyone is 
talking about const again. And I would say reading it should likely be 
mandatory for anyone who wants to venture thinking and posting how the 
const system should work. It describes the issues one faces when 
implementing such a system, and the reference immutability system 
described there is perhaps a good starting point for a system for D.

-- 
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d-learn mailing list