That's why I said that it is ultimately the programmer's responsibility to ensure there are no undesirable side effects.
For instance, the compiler does not know if some area of memory being referenced in some function/procedure is also being referenced by a different function/procedure in another thread. It is the programmer who must know and account for situations like that.
Yes and no. It's the responsibility of the programmer to follow the defined semantics of the language. And in Pascal the defined semantic for a const(ref) parameter is that it will not change during the rumtime, so you as a programmer must make sure that this doesn't happen. It's a two way contract so to speak. You promis to make sure the parameter doesn't change, and in exchange the compiler promises that it generates correct code.
For example, if I compile the following code for 32 and 64 bit I get differing results:
type
TMyRec = record
A: Integer;
end;
procedure Foo(const r: TMyRec; var A: Integer);
begin
A:=42;
WriteLn(r.A);
end;
var
r: TMyRec;
begin
r.A:=32;
Foo(r, r.A);
end.
The reason is that in one case the parameter is passed by register in the other it's passed by reference. This means this code has undefined semantics, which only happens because I broke the promise I made the compiler through passing a "const".
There are just things that you as a programmer must never make assumptions about. It's called undefined behavior and no matter how good you know the language and the compiler, you should never think you know whats happening there.
I had a great experience with C++, because prior to C++20 bit representation (and thereby overflow) for the int types was not defined. So I had a for loop like this:
for (;myvar>0;++myvar) {
...
}
Which should loop until overflow happend, and the compiler just turned it into:
Because overflow is not defined, so the compiler reasoned, a value >0 that will only ever be incremented will never get smaller and therefore this condition can never be met. Mathematically a sound argumentation, but of course vary nasty to figure out in my situation.
Long story short, you as a programmer only ever are responsible to follow the semantics of the language. If something falls outside of the defined behavior of the language, you should not make any assumptions about it