I mentioned or to be exact dreamed about more evolved Pascal enhancement, mentioned it here at once as i recall, but really can't remember any comments or any discussions.
So will write it here as it is relevant for memory safety.
My suggestion is to introduce new modifier(s) to managed (and non managed) variables, this include classes/objects, the new main modifier is "Auto", example
procedure Test(aFileName: string);
var
SList: TStringList; auto; // the compiler will ensure calling the default constructor and destructor
begin
//SList := TStringList.Create; // should stop the compiler with specific Error, you are not allowed to create an auto
SList.LoadFromFile(aFileName);
//SList.Free // should stop the compiler with specific Error, you are not allowed to destreuct/free an auto
end
There is also similar modifier like "init/create" and "free" these will only their part and the compiler will ensure you can't abuse the memory layout or use after free.
This also can be applied to fields in TObject/Class, the compiler will put the default constructor and destructor in their right position and will stop compiling when the code is trying to call constructor and destructor.
But one could say using "auto" for the fields in classes will make initializing slower, no it will not as sooner or later it will initialized or used (except other usage, will follow down), will this cause degradation in performance?, no, not really, after all there is a price for pay.
Another modifier which i can argue will be very helpful, is "delayed" or "onuse".., this one is for places when you don't know if that class will be needed or not, so the compiler will not auto create it !, but will initialize it to 0 (nil), and will check against that nil on every first usage with in the current scope then call the constructor in-place, guaranteeing its readiness, while will enforce calling the destructor in every scope it mentioned (referenced) but again if it is nil then nothing to do.
With "delayed" modifier there is a performance hit for sure but it is merely "if assigned(x)" and as i mentioned above at the first usage in the current scope, so when in doubt i will leave to the compiler but when i am sure i will need that delayed to be ready for lets say a loop, then i can call specific function on it or just touch it in any code so the following code will not have to have the check for creation, of course if such delayed var is used in a loop then the compiler will put the constructor before entering the loop (at the loop limit preparing code)
Also to mention how clean the code will become not just eliminating user after free or use non initialized.
as for compiler: Delphi compiler is already equipped and has the ability to do that so minimal adjusting is needed, it does the same with all managed types (strings, arrays..) for the suggested modifiers above it will be close to this
Currently the compiler does the same with strings and arrays as seen here ( though this is my XE8 so not sure about the latest versions)
for combining the suggested "delayed" with the above the compiler could check for referencing one to another and adjust or rearrange the creation and destruction order.
Anyway, this i this another short by me to reach a discussion about this enhancement or call it evolution, also this is the right evolution toward more memory safety.
There is also can be a suggestion for different modifier "secure" "mute" (or something), with this one the compiler will allow any assigning to referencing (or double referencing), in other words and as example, X is a class, no code such Y := X is allowed, you need X (the object in X) you have to use it where is it which is X, This will ensure specific design and will limit pointer miss using, you want to load a bunch of the like of that X in an array then either declare them there with in the array and use them there, or, custom and precise steps should be done as guarantee to the compiler that this is well thought of, otherwise we need to write better code and design the structure better, another example ; X is secure object and it is a field in the non secure Z, the compiler will not allow to use X out side the scope of this current scope and/or outside the Z, meaning, the compiler will not allow passing X as parameter to a procedure, but will allow Z, X and its value is not allowed to be used in any direct assigning ":=", still we have the ability to introduce assign as operator that will ship or duplicate X fields, but not X itself or its pointer, that pointer should not be reached or allowed to be accessed by the compiler, and when i say compiler i mean the new language constraints for these suggestions.