I'm a bit late for the party, but i still would like to add some info on writable constans.
First of all, as Johan and David stated global and local constants do not differ in memory.
For those interested in usage of writable constants:
I found it useful to emulate "Promise" functionality to make the function "Lazy". Ofcourse delphi doesn't support Promises, so this is only partially efficient.
Consider a function to count amount of words in a string:
function CountWords(Input: String):Integer;
var
Worker: TStringList;
begin
Worker := TStringList.Create;
Worker.DelimitedText := Input;
Result := Worker.Count;
Worker.Free;
end;
Now imagine it beeing called many times in our program. TStringList object will be created and freed each time we do it thus doing extra job.
You could ofcourse solve this by creating a global variable Worker_CountWords, initialize it on program start and use it in your function, but take a look at this:
function CountWords(Input: String):Integer;
{$J+} //Enable writable constants
const
Worker: TStringList = nil;
{$J-} //Disable writable constants
begin
if Worker = nil then
begin
Worker := TStringList.Create;
//Other Initialization code here
end;
Worker.DelimitedText := Input;
Result := Worker.Count;
end;
This function will only create TStringList once and use it later, but will never free it (kind of a downside here). But for a function that can be called any time during the app is running this is sort of suitable. This can make your code look a bit cleaner if you will...
Now, notice - this isn't actually a promise, but it achieves similar results. You could aslo do this with function calls (i've already tried replacing the actual function in memory and it's pretty bad idea, but you could make a const that will hold pointer to function, which at start holds pointer to initialization function and after that replaced to actual worker function and the parent function would only have a call to a function which is held in a constant). I cannot think of a good example right now, so i'll let you figure that one out on your own.
Also it is not required to have {$WRITABLECONST ON} in order to modify constant values, you could also do something like this:
procedure DoSomeWork;
const
FirstCall : TDateTime = 0;
begin
if FirstCall = 0 then
PDateTime(@FirstCall)^ := Now;
Writeln(TimeToStr(FirstCall));
//some actual work here
end;
Same thing applies to const
parameters in functions, because they are exactly same as var
parameters (passed by reference to avoid spending time on creating separate variables), the only difference is that compiler doesn't allow you to change these values normally.
P.S. Be careful with const function parameters, since you can pass actual constants like foo(12)
and trying to modify that could probably mess something up...