Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2021-12

Minor doc error about "const param"

9 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb

Actually an commission, but an important one.

https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4

Specifying a parameter as Constant is giving the compiler a hint that

the contents of the parameter will not be changed by the called routine.

"by the called routine."
Should that not be "by any code (the caller, the called, or any nested callee, or any other thread, interrupt or hardware modifying memory)"? Or maybe "until the called routine has finished, and returned to the caller" ?

Reply by email

Michael Van Canneyt
to Martin Frb
Martin Frb wrote 9 lines
Actually an commission, but an important one. https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 > Specifying a parameter as Constant is giving the compiler a hint that the contents of the parameter will not be changed by the called routine. "by the called routine." Should that not be "by any code (the caller, the called, or any nested callee, or any other thread, interrupt or hardware modifying memory)"?

If the value is copied then nothing else can change it since it is only accessible to the routine itself ? (unless you're doing some really dirty tricks, obviously)

Michael.

Reply by email

Martin Frb
to Michael Van Canneyt
Michael Van Canneyt wrote 20 lines
On Mon, 20 Dec 2021, Martin Frb via fpc-devel wrote: > Actually an commission, but an important one. > > https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 > > > Specifying a parameter as Constant is giving the compiler a hint > that the contents of the parameter will not be changed by the called > routine. > > "by the called routine." > Should that not be "by any code (the caller, the called, or any > nested callee, or any other thread, interrupt or hardware modifying > memory)"? If the value is copied then nothing else can change it since it is only accessible to the routine itself ? (unless you're doing some really dirty tricks, obviously)

In the below example "GlobalTxt := 'abc';" is indeed in the "called routine".
But insert a call to a subroutine doing the work, or start a thread....

procedure foo(const t: AnsiString);
begin
   GlobalTxt := 'abc';
   // do some mem alloc/dealloc work
   // do something with t, it still points to the location that the old
content was in. If that mem has been changed....
end;
var
   GlobalTxt: AnsiString;
begin
   GlobalTxt := getRandomTextWichIsNotAConstant;
   foo(GlobalTxt);
end;

Reply by email

Bart
to Martin Frb: Actually an commission, but an important one.…
PM Martin Frb wrote
https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 > Specifying a parameter as Constant is giving the compiler a hint that the contents of the parameter will not be changed by the called routine.

Actually it is a contract between the programmer and the compiler, telling the compiler that the value of sais constant parameter will not be altered in any way.
The compiler will enforce this as much as it can, but it is up to the programmer to not have other processes alter the value of that parameter, whilst that function is still running.

Any side effects of circumventing the compilers efforst to enforce this are at your own risks.

Bart

Reply by email

Michael Van Canneyt
to Martin Frb: In the below example "GlobalTxt := 'abc';" is indeed in the "called routine". But insert…
Martin Frb wrote 34 lines
On 20/12/2021 12:29, Michael Van Canneyt wrote: > > > On Mon, 20 Dec 2021, Martin Frb via fpc-devel wrote: > >> Actually an commission, but an important one. >> >> https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 >> >> > Specifying a parameter as Constant is giving the compiler a hint >> that the contents of the parameter will not be changed by the called >> routine. >> >> "by the called routine." >> Should that not be "by any code (the caller, the called, or any >> nested callee, or any other thread, interrupt or hardware modifying >> memory)"? > > If the value is copied then nothing else can change it since it is only > accessible to the routine itself ? (unless you're doing some really dirty > tricks, obviously) In the below example "GlobalTxt := 'abc';" is indeed in the "called routine". But insert a call to a subroutine doing the work, or start a thread.... procedure foo(const t: AnsiString); begin   GlobalTxt := 'abc';   // do some mem alloc/dealloc work   // do something with t, it still points to the location that the old content was in. If that mem has been changed....

Well, that's what I meant with really dirty tricks.

I will probably have to rephrase the documentation to 'The compiler will not allow you to modify the parameter value by assigning something directly to it."

Michael.

Reply by email

Michael Van Canneyt
to Bart: On Mon, Dec 20, 2021 at 12:07 PM Martin Frb via fpc-devel Actually it is a contract…
Bart wrote 16 lines
On Mon, Dec 20, 2021 at 12:07 PM Martin Frb via fpc-devel wrote: > https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 > > Specifying a parameter as Constant is giving the compiler a hint that > the contents of the parameter will not be changed by the called routine. Actually it is a contract between the programmer and the compiler, telling the compiler that the value of sais constant parameter will not be altered in any way. The compiler will enforce this as much as it can, but it is up to the programmer to not have other processes alter the value of that parameter, whilst that function is still running. Any side effects of circumventing the compilers efforst to enforce this are at your own risks.

That's what I meant with dirty tricks. There are many ways to do so.

Michael.

Reply by email

Bart
to Adriaan van Os
PM Adriaan van Os wrote
Neither would the compiler allow (I hope) the const parameter to be passed as a var parameter.

It does not:

{$mode objfpc}
{$h+}
procedure foo(var x: integer);
begin
end;
procedure bar(const y: integer);
begin
  foo(y); //line 10
end;
begin
end.
test.pas(10,8) Error: Can't assign values to const variable
Bart

Reply by email

Martin Frb
to Bart
Bart wrote 18 lines
On Fri, Dec 24, 2021 at 12:00 PM Adriaan van Os via fpc-devel wrote: > Neither would the compiler allow (I hope) the const parameter to be passed as a var parameter. It does not: {$mode objfpc} {$h+} procedure foo(var x: integer); begin end; procedure bar(const y: integer); begin foo(y); //line 10 end;

The first quote was probably a ref to the (current) case from the forum, that triggered this.

procedure Foo(const A: String; var B: string);
begin ... end;
var s: string;
Foo(s,s);

It is most likely (but not certain) that B will be modified. And with that A would be modified.

The tricky bits are:
- If A would no longer be accessed after B was modified, then that code will *currently* work.  Yet new optimizations could be added, that affect this (though really unlikely)
- could be a virtual method, and each version only accesses either A or B.
- it can not always be caught "Foo(s1,s2)" could have s1 and s2 have the same var (and with a ref count of 1, if both were "var param" to the caller).

Reply by email