Clarifying 'const' terminology
Sean Kelly
sean at f4.ca
Sat Jul 8 15:03:52 PDT 2006
Bruno Medeiros wrote:
> 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).
In the realm of compiler optimization techniques, there's another issue
as well: can the compiler assume that, because it is evaluating a const
reference, that the underlying data will not change while that reference
is in use. This is the truly sticky part, and is I think a large reason
why Walter hasn't settled on anything yet. For example, consider "const
by default":
void readWrite( inout T val ) {}
void readOnly( in T val ) {}
T val;
readWrite( inout val );
...
readOnly( val );
In the above, because a mutable reference to val is obtained before
readOnly is called, can the compiler assume that the contents of val
will not change while readOnly is being evaluated? Can it ever make
that assumption for the entire life of the program after readWrite is
called?
> 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 = ...;
These two are actually identical. Though things can get a bit tricky if
'int' is replaced by a typedef involving a reference type, which is why
the latter form tends to be preferred these days--it is unambiguous,
unlike the former form.
> const int const * iptr = ...;
> each with different meanings:
I believe this is the same as the above, you merely applied the const to
int twice. What you probably meant for these three was:
const int * iptr = ...; // mutable ptr to const int
int const * iptr = ...; // same as previous line
int * const iptr = ...; // const ptr to mutable int
const int * const iptr = ...; // const ptr to const int
int const * const iptr = ...; // same as previous line
To return to the typedef issue for a moment, if you do:
typedef char* pchar;
template<class T> void func( const T val ) {}
pchar val = "hello";
func( val );
then it's not entirely clear whether the val in func is a const pointer
to mutable data or vice-versa. Thus the preferred method is:
template<class T> void func( T const val ) {}
Where it's obvious that the 'const' will apply to the pointer if one exists.
Sean
More information about the Digitalmars-d-learn
mailing list