'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