It looks like the Delphi compiler does not honor const record parameters when "records-with-methods" are involved.
Having not tried to abuse the const convention previously, I was a little surprised to find the compiler accepted code like that:
type
TTest = record
Field : String;
procedure Update;
end;
procedure TTest.Update;
begin
Field := Field + '+1';
end;
procedure DoStuff(const t : TTest);
begin
ShowMessage(t.Field);
t.Update;
ShowMessage(t.Field);
end;
While if you try to do a
t.Field:='doh';
in DoStuff f.i., the compiler will properly complain, but you're allowed to call methods that modify the "const" record without even a hint or warning. So this is different behavior than for reference types (such as classes or dynamic arrays), where direct field writes are allowed (as const only restricts changes to the parameter itself).
Addendum: this allows to modify declared compile-time constants this way too, as in:
const
cTest : TTest = (Field : '1');
...
cTest.Update; // will show '1' then '1'+'1'
ShowMessage(cTest.Field); // will show '1' (because optimized at compile-time)
Is that an accepted/documented behavior? or just a compiler shortcoming?
Update
directly since it seems to me that is the fundamental issue here. You need a method of the record to mutate a const record. – David HeffernanUpdate
. Value types should be used as immutable. (Link is C# example, sorry, but the idea is the same.) See also this SO answer. – Craig StuntzUpdate
modifies the field value, but we don't get to see the result of that change because the compiler apparently optimizes the direct access to it in the subsequentShowMessage
statement. – Rob KennedyShowMessage
and optimisation was made. At the time I made the edit, I believe it was reasonable. – David Heffernan