'var' and 'volatile' as !const, with invariant-by-default
Russell Lewis
webmaster at villagersonline.com
Mon Jun 25 12:22:25 PDT 2007
So I understand what Walter is going for with the whole
const/invariant/final thing, but it seems that the syntax is causing a
lot of confusion. (I know it isn't clear to me!) People have been
arguing back and forth about const-by-default, and here's my version:
* Invarant-by-default. That is, an unadorned variable (whether it is
a global variable, function local, or parameter) is always invariant.
* Use the keyword 'var' to represent a variable which can be modified.
* Use the keyword 'volatile' to indicate that there are aliases of the
variable, so it is not safe to cache the value of the variable in a
register.
* 'volatile' is illegal on value-types. (Only allowed on pointers,
arrays, class references, etc.)
EXAMPLES:
uint myCompileTimeConstant = 10;
uint my_final_equivalentVariable = DoRuntimeCalculation();
var uint myOrdinaryVariable;
var uint *theOnlyPointerToSomething;
volatile var uint *oneOfManyAliases;
volatile uint *readonlyAlias;
TAKING POINTERS:
The type of the pointer depends on the type of the original variable:
* If the original variable has no modifiers, then the pointer has no
modifiers as well. (Totally readonly)
* If the original variable has 'var', then the pointer has 'volatile'
(the pointer is an alias, and the pointed-to thing might change, but
the pointer must not be used to change the variable, since the
original is NOT marked 'volatile')
* If the original variable has 'volatile', then the pointer has
'volatile'. This means that there may exist some 3rd alias to the
underlying variable which could change it. See note below.
* If the original variable has 'volatile var', then the pointer does as
well.
NOTE: When taking a pointer to 'volatile', you might want to make the
pointer 'volatile var', on the idea that the pointer might be the way
that the original variable is modified. However, 'volatile' is most
useful as a way to pass a reference into a library, and we don't want
the library to accidentally start modifying what was supposed to be
readonly data. To turn on 'var' ALWAYS requires an explicit cast.
IMPLICIT CASTS:
* You can implicitly cast *away* 'var'. To add it in always requires
an explicit cast.
* You can implicitly *add* 'volatile'. To remove it always requires
an explicit cast.
EXAMPLES WITH FUNCTION CALLS:
uint myFunc(uint a,char[] b, myStruct *c);
uint myVolatileAwareFunc(uint a,volatile char[] b,volatile myStruct *c);
var uint globalUint;
var char[] globalArray;
var myStruct globalStruct;
char[] ro_globalArray;
myStruct ro_globalStruct;
ILLEGAL (pointers have 'volatile' tag, parameters don't):
myFunc(globalUint, &globalArray, &globalStruct);
LEGAL (parameters have correct tags):
myVolatileAwareFunc(globalUint, &globalArray, &globalStruct);
myFunc(globalUint, &ro_globalArray, &ro_globalStruct);
NOTE: The first argument in the last call above is legal because uints
are passed by value, not reference, so the parameter is *not* volatile.
Thoughts? I know, to implement this would require a complete rewrite of
existing D code...but let's ignore that for a moment and just as "is it
better?" If so, then we can ask "is it worth the cost of a rewrite?"
Russ
More information about the Digitalmars-d
mailing list