Initialisation of Pointer Variables
Posted: Sat May 25, 2019 3:48 am
In Oberon, as in many (most?) languages, variables are not initialised by the compiler. Eiffel would be a counter example. I am not sure if general automatic initialisation is a Good Thing, as I prefer if the program text is as explicit as possible.
However, there's one exception: pointer variables.
I propose considering to automatically initialise pointers to NIL. In my book, the comprehensive use of precondition checks is a Good Thing, both for procedure parameters as well as other assumptions as regards the validity of a procedure (eg. task state in a scheduler). If a procedure's correctness depends on specific values, or ranges thereof, of its actual parameters, it can easily be ensured using ASSERT statements. Astrobe also implements the ASSERTs in an efficient fashion, so there's little run-time overhead for the much improved safety of the code.
Pointers are different beasts compared to all other types, though. For example, if a module defines (and exports) a pointer type, and a set of related procedures, the latter will require a NEW-initialised pointer parameter. However, the procedure has no way of ASSERTing if the pointer is valid, which is, obviously, crucial for its correctness. If the non-initialised pointer's arbitrary value happens to point into the heap or the stack memory regions, obscure defects can ensue. (There's no run-time error when dereferencing a NIL pointer, probably for performance reasons, given the usual frequency of access.)
One can argue that non-initialised variables are a basic problem, and the programmer's mistake. However, parameters of other types can be checked for validity, pointers cannot. NIL auto-initialisation would remedy that. (I don't know the practical impact of such a change on the current compiler design and implementation of the procedure prologue, module initialisation code, and NEW).
Thoughts?
(The Report does not say anything about this issue, N.W.'s ARM compiler paper says (p. 25): "The value of a pointer variable is the address of the referenced record, or it is NIL, when no record is referenced.")
However, there's one exception: pointer variables.
I propose considering to automatically initialise pointers to NIL. In my book, the comprehensive use of precondition checks is a Good Thing, both for procedure parameters as well as other assumptions as regards the validity of a procedure (eg. task state in a scheduler). If a procedure's correctness depends on specific values, or ranges thereof, of its actual parameters, it can easily be ensured using ASSERT statements. Astrobe also implements the ASSERTs in an efficient fashion, so there's little run-time overhead for the much improved safety of the code.
Pointers are different beasts compared to all other types, though. For example, if a module defines (and exports) a pointer type, and a set of related procedures, the latter will require a NEW-initialised pointer parameter. However, the procedure has no way of ASSERTing if the pointer is valid, which is, obviously, crucial for its correctness. If the non-initialised pointer's arbitrary value happens to point into the heap or the stack memory regions, obscure defects can ensue. (There's no run-time error when dereferencing a NIL pointer, probably for performance reasons, given the usual frequency of access.)
One can argue that non-initialised variables are a basic problem, and the programmer's mistake. However, parameters of other types can be checked for validity, pointers cannot. NIL auto-initialisation would remedy that. (I don't know the practical impact of such a change on the current compiler design and implementation of the procedure prologue, module initialisation code, and NEW).
Thoughts?
(The Report does not say anything about this issue, N.W.'s ARM compiler paper says (p. 25): "The value of a pointer variable is the address of the referenced record, or it is NIL, when no record is referenced.")