On thinking about this a little more I think the issue is that there
are pointer properties which have no corresponding keywords to control
them. Here is a list of pointer properties and associated control
options in C (probably incomplete, definitely not written by a
language specialist, so please forgive incorrect terminology). In
some instances there are keywords to control the property, in others,
not.
1. Pointer may be changed. Examples:
char *ptr;
ptr++;
ptr--;
ptr += offset;
Keyword "const" prevents these operations.
2. Pointer may be used to reference memory at an offset by
sizeof(type). Example:
int *var;
*(var + offset) = var[offset + 1];
No keyword prevents these actions. Stopping these actions comes up in
the context of "single vs. multiple". That is:
int *var;
may reference one int, or it may reference many, and there is
currently no way to tell the compiler which is desired. A keyword to
prevent this action: might be "single". As in:
int single *var;
...
/* compiler throws errors on the next two lines, which would
otherwise be legal */
foo = var[i];
foo = *(var + i);
3. Pointer is used to reference structure elements. Example:
var->element1;
Current keyword - none. Compilers throw errors if var is not a
pointer to a structure with a member named "element1". Additionally
there is opaque typing via typedef. A keyword to prevent this sort of
reference might be "opaque". Possibly useful in a situation where an
opaque type is used in the same file where the non-opaque definitions/
actions are coded. Otherwise, I cannot think of a situation where it
would be used.
4. memory allocation/free/reallocation via (void *).
Current keyword - const. But const doesn't really do much for the
situations where more than one pointer is used to reference an
allocated region, which can lead to "memory confusion". Example:
int *array=malloc(BIGNUMBER*sizeof(int));
int *oneptr;
int *twoptr;
oneptr=array;
twoptr=array;
...
/* far away in the code */
free(oneptr);
...
/* and later */
free(twoptr);
The first free() may or may not be an error, but the second one
certainly is. Const really doesn't get us out of this because we
might have assigned two pointers as in this case. A keyword "primary"
could clarify this situation (and should probably additionally have
the same effect as "const"), like:
int *array=NULL;
int primary *oneptr=NULL; /* an "official" memory reference */
int *twoptr=NULL;
array=malloc(BIGNUMBER*sizeof(int)); /* still works! */
oneptr=(int primary *)array; /* official reference filled */
/* forbidden: two primary pointers for the same memory
int primary *threeptr = oneptr;
*/
twoptr=array; /* no problem, neither is a primary */
...
/* far away in the code we run into this, which is fine,
because oneptr is a primary */
pfree(oneptr);
...
/* and later this, which is an error */
pfree(twoptr);
where
void pfree(void primary *address){}
similarly:
void primary *pmalloc(size);
/*etc.*/
Here adding the keyword would require new functions, because
currently
C treats all pointers as if they were "primary", and so free() etc.
cannot be easily modified in a backwards compatible manner to
implement this. Well, we could define "secondary", and have the
compiler flag calls to free() with secondary pointers, but "secondary"
would have to be applied to pretty much every pointer, which would be
awful. Primary, on the other hand, would affect fewer pointers.
5. reference at different scope, specifically, allowing a reference
outside of its defined scope. Example:
void function(int **var){
int localvar;
*var = &localvar;
}
...
int *var;
function(&var);
/* var points to nothing useful here, prepare to segfault */
Current keyword to control this - none. Current keyword to mediate
the effect (by changing the scope of the memory) is "static". A
keyword to disable this might be "local". Where
void function(int **var){
int localvar;
local int *ptr;
ptr=&localvar; /* this is OK, local references in scope */
function1(localvar); /* still good */
function2(ptr); /* <- here is where it gets complicated!!! */
/* compiler throws an error at the next line with something like:
"out of scope reference forbidden by local keyword"
*/
*var = &localvar;
}
and of course this would still be fine:
void function(int **var){
static int localvar;
*var = &localvar;
}
The logic cannot be inverted with "global" instead of "local", as it
won't be backwards compatible, because currently all pointers are
"global", and they would have to default to "local" for "global" to be
the keyword.
6. casting of pointers. Some of the situations above can reappear
when pointers are dereferenced. Example:
function(STRUCTDEF *holder){
}
STRUCTDEF **holder; /* an array of holder pointers */
...
/* in this instance, a pointer to a single STRUCTDEF, not
to an array of STRUCTDEFs */
function( &(holder[i]) );
this is back to the many vs. single issue from (2). So to fully
specify
what is intended this would become:
function(STRUCTDEF single *holder){
}
STRUCTDEF **holder; /* an array of holder pointers */
...
function( (STRUCTDEF single *)(&(holder[i]) );
which suggests that this type of keyword could be applied in the "more
restrictive" direction in casts, as is "const" now.
Regards,
David Mathog
|