Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 14:22, Sven Barth via fpc-devel wrote:
Only because you can't see a reason for it doesn't mean that it 
doesn't exist.


That is exactly why I asked :)

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Sven Barth via fpc-devel
Ondrej Pokorny via fpc-devel  schrieb am
Do., 2. Feb. 2023, 12:09:

> Delphi cannot do it. FPC rocks!
>
> The only disadvantage is that you get a FreeAndNil copy for every type
> you pass into the parameter (?)
>
> Do we want to change it in SysUtils? :)
>

As you might have noticed you need to add a modeswitch to enable this and
this modeswitch is there for a reason (namely that this could lead to wrong
code being used). So by default no one would benefit from this addition and
probably not even know that it's there.

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Sven Barth via fpc-devel
Ondrej Pokorny via fpc-devel  schrieb am
Do., 2. Feb. 2023, 10:06:

> On 02.02.2023 07:42, Sven Barth via fpc-devel wrote:
> > The case when you *need* a constant reference. Case in point: the
> > passing of TGuid in IInterface.QueryInterface. Delphi code relies on
> > it being a reference, but “const” does not guarantee that for all
> > platforms.
>
> Maybe I am missing something, could you please explain why
> IInterface.QueryInterface needs constref?
>

This isn't about Delphi, but about Windows (and XPCOM): there the IID
parameter is declared as "REFIID" which is essentially a pointer. On x86
with stdcall this is not a problem, because there "const TGUID" will be
passed as reference, same on x86_64 and also ARM64. However on ARM this is
*not* the case (and which is how that issue was discovered). So to avoid
having to add a cast to a PGUID to every QueryInterface call we instead
decided to introduce "constref" which results in fewer modifications for
existing code.

Maybe somebody knows a real use case?
>

There are cases were you really need a reference and want it to be const.
Or were you want to avoid a copy *for sure* (e.g. Embedded targets).

Only because you can't see a reason for it doesn't mean that it doesn't
exist.

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 12:19, Marco van de Voort via fpc-devel wrote:

On 2-2-2023 12:00, Ondrej Pokorny via fpc-devel wrote:
The only disadvantage is that you get a FreeAndNil copy for every 
type you pass into the parameter (?)
Are they actually made global ? Will two freeandnil in 
different units use the same?


But that is just curiousity, IMHO this remedy is worse than problem. 
Obviously even.


In case FreeAndNil is inlined, there is no problem, is there?

generic procedure FreeAndNil(var Obj: T); inline;
var
  Temp: TObject;
begin
  Temp := Obj;
  Obj := nil;
  Temp.Free;
end;

I checked now and on i386-win32 the generic FreeAndNil is actually inlined:

program test;

{$mode objfpc}{$h+}
{$modeswitch ImplicitFunctionSpecialization}

generic procedure FreeAndNil(var Obj: T);
var
  Temp: TObject;
begin
  Temp := Obj;
  Obj := nil;
  Temp.Free;
end;

type
  TSomeObject = class(TObject);
  TSomeObject2 = class(TObject);

var
  X: TSomeObject;
  X2: TSomeObject2;
const
  IsNil: array[Boolean] of string = ('nil', 'assigned');
begin
  X := TSomeObject.Create;
  X2 := TSomeObject2.Create;
  FreeAndNil(X);
  FreeAndNil(X2);
  Writeln('X  ', IsNil[Assigned(X)]);
  Writeln('X2 ', IsNil[Assigned(X2)]);

  ReadLn;
end.

So everything good!

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 12:25, Mattias Gaertner via fpc-devel wrote:

On Thu, 2 Feb 2023 12:00:31 +0100
Ondrej Pokorny via fpc-devel  wrote:


[...]
Delphi cannot do it. FPC rocks!

+1


The only disadvantage is that you get a FreeAndNil copy for every
type you pass into the parameter (?)

Do we want to change it in SysUtils? :)

I got a feeling this solves a problem no one had.


I agree with that.

But you know, pascal is strongly typed. You should get a compiler 
warning when passing an incompatible parameter and not an AV in runtime. 
Like the Pos(Variant) issue :)


Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Mattias Gaertner via fpc-devel
On Thu, 2 Feb 2023 12:19:46 +0100
Marco van de Voort via fpc-devel  wrote:

> On 2-2-2023 12:00, Ondrej Pokorny via fpc-devel wrote:
> >
> >
> > The only disadvantage is that you get a FreeAndNil copy for every
> > type you pass into the parameter (?)  
> 
> Are they actually made global ?

yes

> Will two freeandnil in different units use the same?

yes (except for packages).

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Marco van de Voort via fpc-devel



On 2-2-2023 12:00, Ondrej Pokorny via fpc-devel wrote:



The only disadvantage is that you get a FreeAndNil copy for every type 
you pass into the parameter (?)


Are they actually made global ? Will two freeandnil in 
different units use the same?


But that is just curiousity, IMHO this remedy is worse than problem. 
Obviously even.



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Mattias Gaertner via fpc-devel
On Thu, 2 Feb 2023 12:00:31 +0100
Ondrej Pokorny via fpc-devel  wrote:

>[...]
> Delphi cannot do it. FPC rocks!

+1

> The only disadvantage is that you get a FreeAndNil copy for every
> type you pass into the parameter (?)
> 
> Do we want to change it in SysUtils? :)

I got a feeling this solves a problem no one had.


Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 11:00, Michael Van Canneyt via fpc-devel wrote:

In userspace, the best seems

Function FreeAndNil(Obj : T) : T;

begin
  Obj.Free;
  Result:=Nil;
end;

With automatic type inference for generics, this allows you to do

A:=FreeAndNil(A);


Michael, bringing your idea to the next step, FPC can do it !!!

program test;

{$mode objfpc}{$h+}
{$modeswitch ImplicitFunctionSpecialization}

generic procedure FreeAndNil(var Obj: T);
var
  Temp: TObject;
begin
  Temp := Obj;
  Obj := nil;
  Temp.Free;
end;

type
  TSomeObject = class(TObject);

var
  X: TSomeObject;
begin
  X := TSomeObject.Create;
  FreeAndNil(X);
  if Assigned(X) then
    Writeln('assigned')
  else
    Writeln('nil');
  ReadLn;
end.

-

Delphi cannot do it. FPC rocks!

The only disadvantage is that you get a FreeAndNil copy for every type 
you pass into the parameter (?)


Do we want to change it in SysUtils? :)

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Sven Barth via fpc-devel
Adriaan van Os via fpc-devel  schrieb am
Do., 2. Feb. 2023, 09:57:

> Sven Barth wrote:
> > Adriaan van Os via fpc-devel  > > schrieb am Do., 2. Feb. 2023,
> > 02:47:
> >
> > Sven Barth via fpc-devel wrote:
> >
> >  > There is no full documentation for that parameter modifier
> (someone
> >  > might want to file a bug report for that), but the documentation
> for
> >  > “const” (
> >  >
> >
> https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4
> >
> >  > ) contains this:
> >  >
> >  > === doc begin ===
> >  >
> >  > Contrary to Delphi, no assumptions should be made about how const
> >  > parameters are passed to the underlying routine. In particular,
> the
> >  > assumption that parameters with large size are passed by
> > reference is
> >  > not correct. For this the constref parameter type should be used,
> > which
> >  > is available as of version 2.5.1 of the compiler.
> >  >
> >  > === doc end ===
> >
> > On debate, see FPC issue 17442.
> >
> >
> > There is no debate planned for this in the near future. So even if this
> > might change some time in the future it does not *now* and very likely
> > also not for 3.4.0. Not to mention that things wouldn't change for most
> > platforms anyway, because they only have the platform ABI available and
> > that *must not* change for compatibility with C code.
>
> "Will not change" and "ABI" are non arguments. They do not address the
> questions put forward here:
>
> - under what circumstances (and in what compiler mode) does FPC pass large
> (say 1 MB or 1 GB)
> "const" parameters by value (which is extremely inefficient) ?
> - for what reasons ?
>
> As long as these questions are not addressed and cleared and documented
> "const" parameters are not
> a useable in actual code.
>

We do not document these on purpose, because they're mainly dictated by the
platform ABI (on the majority of targets FPC supports simply the C ABI is
used). The main part of "const" is that you can't (easily) modify the value
and that reference counting isn't done when passing the value around.
Whether it's passed by-value or by-reference is irrelevant for that.
If you need pass-by-reference then use those modifiers that are intended
for them, namely "var", "out" and "constref".

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Michael Van Canneyt via fpc-devel




On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:


On 02.02.2023 10:22, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:

On 02.02.2023 10:15, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
I myself cannot think of any real use case of constref other than hacks 
like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a 
const - it used to be an untyped var). As a result FreeAndNil allows you 
to happily pass read-only properties to it that are then nilled.


Which is a clear violation of the concept of Const... :/


Exactly.


Probably an ill-advised "fix" to the problem that FreeAndNil accepted an 
untyped var

and you could basically pass anything.


Yes. Solving one problem by creating a different one. The best would be if 
the FreeAndNil declaration alternated between constref and untyped var 
between builds. In that case you would be able to hunt both the issues :)


Seriously, having a [loose] modifier would be much more useful, IMO:

FreeAndNil(var [loose] Obj: TObject);

That would allow you to pass any TObject descendant.


It would solve this problem, but introduces another problem, since it would be
usable anywhere:

Procedure DoSomething(var [loose] Obj: TObject);

var
  a : TSomeObject;

begin
  a:=TSomeobject.Create;
  DoSomething(a);
end;

after DoSomething, A may contain a class that is not a TSomeObject at all,
leading to more problems.

In userspace, the best seems

Function FreeAndNil(Obj : T) : T;

begin
  Obj.Free;
  Result:=Nil;
end;

With automatic type inference for generics, this allows you to do

A:=FreeAndNil(A);

Which is quite acceptable IMO. If you could add inline to the generic
definition the overhead would be minimal.

As it is, FreeAndNil() seems like another candidate for a compiler intrinsic ;-)

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 10:22, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:

On 02.02.2023 10:15, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
I myself cannot think of any real use case of constref other than 
hacks like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a 
const - it used to be an untyped var). As a result FreeAndNil 
allows you to happily pass read-only properties to it that are then 
nilled.


Which is a clear violation of the concept of Const... :/


Exactly.


Probably an ill-advised "fix" to the problem that FreeAndNil accepted 
an untyped var

and you could basically pass anything.


Yes. Solving one problem by creating a different one. The best would be 
if the FreeAndNil declaration alternated between constref and untyped 
var between builds. In that case you would be able to hunt both the 
issues :)


Seriously, having a [loose] modifier would be much more useful, IMO:

FreeAndNil(var [loose] Obj: TObject);

That would allow you to pass any TObject descendant.

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Michael Van Canneyt via fpc-devel




On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:


On 02.02.2023 10:15, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
I myself cannot think of any real use case of constref other than hacks 
like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a const 
- it used to be an untyped var). As a result FreeAndNil allows you to 
happily pass read-only properties to it that are then nilled.


Which is a clear violation of the concept of Const... :/


Exactly.


Probably an ill-advised "fix" to the problem that FreeAndNil accepted an 
untyped var
and you could basically pass anything.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Michael Van Canneyt via fpc-devel



On Thu, 2 Feb 2023, Hairy Pixels via fpc-devel wrote:





On Feb 2, 2023, at 3:57 PM, Adriaan van Os via fpc-devel 
 wrote:

- under what circumstances (and in what compiler mode) does FPC pass large (say 1 MB or 1 
GB) "const" parameters by value (which is extremely inefficient) ?
- for what reasons ?

As long as these questions are not addressed and cleared and documented "const" 
parameters are not a useable in actual code.


That’s what I want to know.  There should be a hard rule like records over
X bytes are passed by reference.  In the issue you posted they said they
had a massive performance penalty in their library because const was
passing by value and this makes people like myself paranoid so I’m
inclined to use constref everywhere with larger records.


It depends on the platform ABI, and hence we don't document it.

I don't see your problem, to be honest:

You want to indicate a parameter to a function cannot be changed in its 
implementation.

If you don't care about how it is passed, use const.

If really want a reference to be passed for performance or other reasons, use 
constref.

So you're doing the right thing by using constref.

Couldn't be simpler.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 10:15, Michael Van Canneyt via fpc-devel wrote:

On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:
I myself cannot think of any real use case of constref other than 
hacks like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a 
const - it used to be an untyped var). As a result FreeAndNil allows 
you to happily pass read-only properties to it that are then nilled.


Which is a clear violation of the concept of Const... :/


Exactly.

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Michael Van Canneyt via fpc-devel



On Thu, 2 Feb 2023, Ondrej Pokorny via fpc-devel wrote:


On 02.02.2023 07:42, Sven Barth via fpc-devel wrote:
The case when you *need* a constant reference. Case in point: the 
passing of TGuid in IInterface.QueryInterface. Delphi code relies on 
it being a reference, but “const” does not guarantee that for all 
platforms.


Maybe I am missing something, could you please explain why 
IInterface.QueryInterface needs constref?


IIRC Joost introduced it at some point, but I don't remember exactly why.

I seem to remember constref was introduced as the equivalent of const * 
parameters in C.
It allows to skip the pointer.


  function TObject.GetInterface(const iid : tguid;out obj) : boolean;

that has a const without ref.

---

I myself cannot think of any real use case of constref other than hacks 
like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a 
const - it used to be an untyped var). As a result FreeAndNil allows you 
to happily pass read-only properties to it that are then nilled.


Which is a clear violation of the concept of Const... :/

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Hairy Pixels via fpc-devel


> On Feb 2, 2023, at 3:57 PM, Adriaan van Os via fpc-devel 
>  wrote:
> 
> - under what circumstances (and in what compiler mode) does FPC pass large 
> (say 1 MB or 1 GB) "const" parameters by value (which is extremely 
> inefficient) ?
> - for what reasons ?
> 
> As long as these questions are not addressed and cleared and documented 
> "const" parameters are not a useable in actual code.

That’s what I want to know. There should be a hard rule like records over X 
bytes are passed by reference. In the issue you posted they said they had a 
massive performance penalty in their library because const was passing by value 
and this makes people like myself paranoid so I’m inclined to use constref 
everywhere with larger records.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Ondrej Pokorny via fpc-devel

On 02.02.2023 07:42, Sven Barth via fpc-devel wrote:
The case when you *need* a constant reference. Case in point: the 
passing of TGuid in IInterface.QueryInterface. Delphi code relies on 
it being a reference, but “const” does not guarantee that for all 
platforms.


Maybe I am missing something, could you please explain why 
IInterface.QueryInterface needs constref?


Delphi definition doesn't use it (Delphi 11):

  IInterface = interface
    ['{---C000-0046}']
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

FPC uses it in the definition:

   IUnknown = interface
 ['{---C000-0046}']
 function QueryInterface({$IFDEF 
FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : 
longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
 function _AddRef : longint;{$IFNDEF 
WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
 function _Release : longint;{$IFNDEF 
WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};

   end;

but when I check all the implementations of QueryInterface in objpas.inc 
I see that the iid is paased to TObject.QueryInterface


  function TObject.GetInterface(const iid : tguid;out obj) : boolean;

that has a const without ref.

---

I myself cannot think of any real use case of constref other than hacks 
like the FreeAndNil in recent Delphi versions:


procedure FreeAndNil(const [ref] Obj: TObject);

that needs the ref because it changes it to nil (so is not really a 
const - it used to be an untyped var). As a result FreeAndNil allows you 
to happily pass read-only properties to it that are then nilled.


Maybe somebody knows a real use case?

Ondrej

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Adriaan van Os via fpc-devel

Sven Barth wrote:
Adriaan van Os via fpc-devel > schrieb am Do., 2. Feb. 2023, 
02:47:


Sven Barth via fpc-devel wrote:

 > There is no full documentation for that parameter modifier (someone
 > might want to file a bug report for that), but the documentation for
 > “const” (
 >

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

 > ) contains this:
 >
 > === doc begin ===
 >
 > Contrary to Delphi, no assumptions should be made about how const
 > parameters are passed to the underlying routine. In particular, the
 > assumption that parameters with large size are passed by
reference is
 > not correct. For this the constref parameter type should be used,
which
 > is available as of version 2.5.1 of the compiler.
 >
 > === doc end ===

On debate, see FPC issue 17442.


There is no debate planned for this in the near future. So even if this 
might change some time in the future it does not *now* and very likely 
also not for 3.4.0. Not to mention that things wouldn't change for most 
platforms anyway, because they only have the platform ABI available and 
that *must not* change for compatibility with C code. 


"Will not change" and "ABI" are non arguments. They do not address the 
questions put forward here:

- under what circumstances (and in what compiler mode) does FPC pass large (say 1 MB or 1 GB) 
"const" parameters by value (which is extremely inefficient) ?

- for what reasons ?

As long as these questions are not addressed and cleared and documented "const" parameters are not 
a useable in actual code.


Regards,

Adriaan van Os

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Michael Van Canneyt via fpc-devel



On Thu, 2 Feb 2023, Sven Barth via fpc-devel wrote:


Am 02.02.2023 um 02:09 schrieb Hairy Pixels:


On Feb 2, 2023, at 4:38 AM, Sven Barth  

wrote:


Which types are passed by-value or by-reference when using const is 
determined by the size of the record and the types of the fields based on 
whatever the corresponding ABI defines (e.g. the x86_64 Sys V ABI is rather 
explicit about some field combinations). The compiler will however not switch 
between passing a specific type once by-value and another time by-reference.
So if the compiler is making the choice using const which is more efficient 
then we should be using const always I would think? What problem does 
constref solve then?


The case when you *need* a constant reference. Case in point: the 
passing of TGuid in IInterface.QueryInterface. Delphi code relies on it 
being a reference, but “const” does not guarantee that for all platforms.


Exactly. That is why they introduced [ref], which serves essentially the same 
purpose as
constref.

https://docwiki.embarcadero.com/RADStudio/Sydney/en/Parameters_(Delphi)#Constant_Parameters

We were way ahead of them on that particular one. 
Benefits of being cross-platform since a long time :-)


Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-02 Thread Steve Litt via fpc-devel
Bart via fpc-devel said on Wed, 1 Feb 2023 11:30:37 +0100

>Hi,
>

>The function is not supposed to alter the contents of this
>datastructure. So, I need to pass this structure by reference.
>(I've spent hours and hours looking at unexpected results in my
>program because I passed the datastructure by value, so the returned
>pointer was in fact garbage...)

I haven't done much Pascal programming this century, but in my C
programming, regardless of the way the structure is passed in, the
returned pointer shouldn't be garbage unless either:

* You're returning a local pointer that goes out of scope outside the
  function, or,

* There's an error inside your function.

You could deduce which by looking at the contents of the pointer just
before your function ends. If it's garbage, your function has an error.
If not, check to see if you're returning a pointer that's a local
variable, because in C at least, doing so causes problems: Often
intermittent problems.

SteveT

Steve Litt 
Autumn 2022 featured book: Thriving in Tough Times
http://www.troubleshooters.com/bookstore/thrive.htm
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Adriaan van Os via fpc-devel

Sven Barth via fpc-devel wrote:

I doubt that records larger than say 4 register widths are ever passed 
by-value. But I definitely can't exclude it, cause I don't know every 
ABI of every platform by heart. So if you want details there then study 
the ABIs of the platforms you use.


I doubt that any ABI would say something about Pascal "const" rather than C "const". So, that 
argument doesn't hold. The only reason I can possibly think of (for "const" to pass large 
parameters by value and thus violating the rule that "const" chooses the most efficient method) is 
compatibility with Delphi in delphi compiler mode. If that's true, which I don't know, it should be 
documented. Otherwise, "const" will continue to puzzle programmers - and in a year we will have the 
same discussion again.


Regards,

Adriaan van Os
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Sven Barth via fpc-devel
Adriaan van Os via fpc-devel  schrieb am
Do., 2. Feb. 2023, 02:47:

> Sven Barth via fpc-devel wrote:
>
> > There is no full documentation for that parameter modifier (someone
> > might want to file a bug report for that), but the documentation for
> > “const” (
> >
> https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4
> > ) contains this:
> >
> > === doc begin ===
> >
> > Contrary to Delphi, no assumptions should be made about how const
> > parameters are passed to the underlying routine. In particular, the
> > assumption that parameters with large size are passed by reference is
> > not correct. For this the constref parameter type should be used, which
> > is available as of version 2.5.1 of the compiler.
> >
> > === doc end ===
>
> On debate, see FPC issue 17442.
>

There is no debate planned for this in the near future. So even if this
might change some time in the future it does not *now* and very likely also
not for 3.4.0. Not to mention that things wouldn't change for most
platforms anyway, because they only have the platform ABI available and
that *must not* change for compatibility with C code.

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Sven Barth via fpc-devel

Am 02.02.2023 um 02:09 schrieb Hairy Pixels:



On Feb 2, 2023, at 4:38 AM, Sven Barth  wrote:

Which types are passed by-value or by-reference when using const is determined 
by the size of the record and the types of the fields based on whatever the 
corresponding ABI defines (e.g. the x86_64 Sys V ABI is rather explicit about 
some field combinations). The compiler will however not switch between passing 
a specific type once by-value and another time by-reference.

So if the compiler is making the choice using const which is more efficient 
then we should be using const always I would think? What problem does constref 
solve then?


The case when you *need* a constant reference. Case in point: the 
passing of TGuid in IInterface.QueryInterface. Delphi code relies on it 
being a reference, but “const” does not guarantee that for all platforms.




You go on to show this:

=== doc begin ===

Contrary to Delphi, no assumptions should be made about how const parameters 
are passed to the underlying routine. In particular, the assumption that 
parameters with large size are passed by reference is not correct. For this the 
constref parameter type should be used, which is available as of version 2.5.1 
of the compiler.

=== doc end ===

Is there anytime a large record should be passed by value if the function is not 
altering the it? This is why I started using constref, i.e. "In particular, the 
assumption that parameters with large size are passed by reference is not correct” 
which makes me think if I have a record of say 64k if I don’t use constref it could 
be passed by value to a function which is called in a tight loop.


I doubt that records larger than say 4 register widths are ever passed 
by-value. But I definitely can't exclude it, cause I don't know every 
ABI of every platform by heart. So if you want details there then study 
the ABIs of the platforms you use.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Hairy Pixels via fpc-devel


> On Feb 2, 2023, at 8:41 AM, Adriaan van Os via fpc-devel 
>  wrote:
> 
> On debate, see FPC issue 17442.

https://gitlab.com/freepascal.org/fpc/source/-/issues/17442

Yes this is what I remember learning.

What I think should be documented is what you should do for records that over a 
certain size. In my old code I have some 64k records and I starting using 
constref with but would using “const” be sufficient to pass by reference also?

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Adriaan van Os via fpc-devel

Hairy Pixels via fpc-devel wrote:



On Feb 2, 2023, at 4:38 AM, Sven Barth  wrote:

Which types are passed by-value or by-reference when using const is determined 
by the size of the record and the types of the fields based on whatever the 
corresponding ABI defines (e.g. the x86_64 Sys V ABI is rather explicit about 
some field combinations). The compiler will however not switch between passing 
a specific type once by-value and another time by-reference.


So if the compiler is making the choice using const which is more efficient 
then we should be using const always I would think? What problem does constref 
solve then?

You go on to show this:

=== doc begin ===

Contrary to Delphi, no assumptions should be made about how const parameters are passed to the underlying routine. In particular, the assumption that parameters with large size are passed by reference is not correct. For this the constref parameter type should be used, which is available as of version 2.5.1 of the compiler. 


=== doc end ===

Is there anytime a large record should be passed by value if the function is not 
altering the it? This is why I started using constref, i.e. "In particular, the 
assumption that parameters with large size are passed by reference is not correct” 
which makes me think if I have a record of say 64k if I don’t use constref it could 
be passed by value to a function which is called in a tight loop.


Yes, to me this notion in the docs lacks all logic. How could copying large parameters ever be 
efficient ? It invites developers to use constref for a purpose it wasn't meant for. For a debate, 
see FPC Issue 17442. Jonas Maebe writes there


"We are adding support for a "constref" parameter to the compiler that 
will
allow you to specify that a parameter is const and must be passed by
reference, but I would strongly suggest to use it only for compatibility
with external APIs (that e.g. use "const struct *" parameters) and very
sparingly for optimization, because in many cases you may well slow down
your code rather than speeding it up."

but also

"Maybe another developer believes that for non-cdecl, we could modify 
the
behaviour of const so that very large records are passed by reference,
which is why I leave this bug open."

If my memory is correct, that this was changed for macpas mode (passing very large records by 
reference) but can't find it back in the bug database.


Regards,

Adraan van Os



___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Adriaan van Os via fpc-devel

Sven Barth via fpc-devel wrote:

There is no full documentation for that parameter modifier (someone 
might want to file a bug report for that), but the documentation for 
“const” ( 
https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 
) contains this:


=== doc begin ===

Contrary to Delphi, no assumptions should be made about how const 
parameters are passed to the underlying routine. In particular, the 
assumption that parameters with large size are passed by reference is 
not correct. For this the constref parameter type should be used, which 
is available as of version 2.5.1 of the compiler.


=== doc end ===


On debate, see FPC issue 17442.

Regards,

Adriaan van Os
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Hairy Pixels via fpc-devel


> On Feb 2, 2023, at 4:38 AM, Sven Barth  wrote:
> 
> Which types are passed by-value or by-reference when using const is 
> determined by the size of the record and the types of the fields based on 
> whatever the corresponding ABI defines (e.g. the x86_64 Sys V ABI is rather 
> explicit about some field combinations). The compiler will however not switch 
> between passing a specific type once by-value and another time by-reference.

So if the compiler is making the choice using const which is more efficient 
then we should be using const always I would think? What problem does constref 
solve then?

You go on to show this:

=== doc begin ===

Contrary to Delphi, no assumptions should be made about how const parameters 
are passed to the underlying routine. In particular, the assumption that 
parameters with large size are passed by reference is not correct. For this the 
constref parameter type should be used, which is available as of version 2.5.1 
of the compiler. 

=== doc end ===

Is there anytime a large record should be passed by value if the function is 
not altering the it? This is why I started using constref, i.e. "In particular, 
the assumption that parameters with large size are passed by reference is not 
correct” which makes me think if I have a record of say 64k if I don’t use 
constref it could be passed by value to a function which is called in a tight 
loop.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Michael Van Canneyt via fpc-devel



On Wed, 1 Feb 2023, Sven Barth via fpc-devel wrote:


Am 01.02.2023 um 11:30 schrieb Bart via fpc-devel:

I thought that constref would be OK for that (the word constref
suggests to me tah the paramter will be treated (by me) to be a
constant, and that it shall be passed by reference in all cases,
whereas with a const parameter the compiler decides upon the best way
to pass it: by value or by reference).
I tried to find documentation for constref, but all I could find was:
https://wiki.freepascal.org/FPC_New_Features_2.6.0#Constref_parameter_modifier
There it says:
"Note that in general, it should only be used for interfacing with
external code or when writing assembler routines."


“constref” is guaranteed to pass the parameter by reference. And the compiler 
will ensure that it can't be modified as reasonably possible (as with “const” 
there are ways to circumvent this, e.g. by passing around a pointer to the 
parameter, but the general cases are covered).

(B.t.w.: Where can I find the official documentation on constref?)


There is no full documentation for that parameter modifier (someone might 
want to file a bug report for that), but the documentation for “const” ( 
https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 
) contains this:


No need for a bugreport, this already is changed in trunk docs:

https://www.freepascal.org/daily/doc/ref/refsu68.html#x184-20800014.4.4

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Sven Barth via fpc-devel

Am 01.02.2023 um 11:30 schrieb Bart via fpc-devel:

I thought that constref would be OK for that (the word constref
suggests to me tah the paramter will be treated (by me) to be a
constant, and that it shall be passed by reference in all cases,
whereas with a const parameter the compiler decides upon the best way
to pass it: by value or by reference).
I tried to find documentation for constref, but all I could find was:
https://wiki.freepascal.org/FPC_New_Features_2.6.0#Constref_parameter_modifier
There it says:
"Note that in general, it should only be used for interfacing with
external code or when writing assembler routines."


“constref” is guaranteed to pass the parameter by reference. And the 
compiler will ensure that it can't be modified as reasonably possible 
(as with “const” there are ways to circumvent this, e.g. by passing 
around a pointer to the parameter, but the general cases are covered).

(B.t.w.: Where can I find the official documentation on constref?)


There is no full documentation for that parameter modifier (someone 
might want to file a bug report for that), but the documentation for 
“const” ( 
https://www.freepascal.org/docs-html/current/ref/refsu67.html#x183-20700014.4.4 
) contains this:


=== doc begin ===

Contrary to Delphi, no assumptions should be made about how const 
parameters are passed to the underlying routine. In particular, the 
assumption that parameters with large size are passed by reference is 
not correct. For this the constref parameter type should be used, which 
is available as of version 2.5.1 of the compiler.


=== doc end ===

Regards,
Sven___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Sven Barth via fpc-devel

Am 01.02.2023 um 15:40 schrieb Hairy Pixels via fpc-devel:



On Feb 1, 2023, at 8:27 PM, Michael Van Canneyt via fpc-devel 
 wrote:

That's exactly what Adriaan is saying. With const the compiler can choose.
With constref, you force it not to copy. But this is not so efficient for
small parameter sizes.

So const will always pass records that are over a certain size by references? 
That’s good to know since “const” is more pleasant to look at it than constref. 
:)
Which types are passed by-value or by-reference when using const is 
determined by the size of the record and the types of the fields based 
on whatever the corresponding ABI defines (e.g. the x86_64 Sys V ABI is 
rather explicit about some field combinations). The compiler will 
however not switch between passing a specific type once by-value and 
another time by-reference.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Tomas Hajny via fpc-devel

On 2023-02-01 15:40, Hairy Pixels via fpc-devel wrote:
On Feb 1, 2023, at 8:27 PM, Michael Van Canneyt via fpc-devel 
 wrote:


That's exactly what Adriaan is saying. With const the compiler can 
choose.
With constref, you force it not to copy. But this is not so efficient 
for

small parameter sizes.


So const will always pass records that are over a certain size by
references? That’s good to know since “const” is more pleasant to look
at it than constref. :)


As written above, the compiler can choose with const (and the choice may 
differ for different CPUs and other factors), i.e. you shouldn't make 
assumptions / rely on const of particular size to be passed by 
reference.


Tomas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Michael Van Canneyt via fpc-devel



On Wed, 1 Feb 2023, Hairy Pixels via fpc-devel wrote:





On Feb 1, 2023, at 8:27 PM, Michael Van Canneyt via fpc-devel 
 wrote:

That's exactly what Adriaan is saying. With const the compiler can choose.
With constref, you force it not to copy. But this is not so efficient for
small parameter sizes.


So const will always pass records that are over a certain size by
references?  That’s good to know since “const” is more pleasant to look at
it than constref.  :)


As I wrote: The compiler can choose. 
Whether it will always do what you think it should do is another matter.


It's not for no reason that constref was introduced: to leave the compiler no
choice...

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Hairy Pixels via fpc-devel


> On Feb 1, 2023, at 8:27 PM, Michael Van Canneyt via fpc-devel 
>  wrote:
> 
> That's exactly what Adriaan is saying. With const the compiler can choose.
> With constref, you force it not to copy. But this is not so efficient for
> small parameter sizes.

So const will always pass records that are over a certain size by references? 
That’s good to know since “const” is more pleasant to look at it than constref. 
:)

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Michael Van Canneyt via fpc-devel



On Wed, 1 Feb 2023, Hairy Pixels via fpc-devel wrote:





On Feb 1, 2023, at 8:16 PM, Adriaan van Os via fpc-devel 
 wrote:

Because, if e.g. the byte-size of a parameter is such that it fits into a CPU 
register, then passing the parameter itself is more efficient than passing a 
reference to it. For large byte-size parameters, const and constref function 
the same. The difference is with small byte-size parameters.


Hmmm I was told otherwise by one of the compiler devs and that I should use 
constref if I want to guarantee it will not be copied. Maybe one of them can 
confirm this….


That's exactly what Adriaan is saying. With const the compiler can choose.
With constref, you force it not to copy. But this is not so efficient for
small parameter sizes.

Michael.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Hairy Pixels via fpc-devel


> On Feb 1, 2023, at 8:16 PM, Adriaan van Os via fpc-devel 
>  wrote:
> 
> Because, if e.g. the byte-size of a parameter is such that it fits into a CPU 
> register, then passing the parameter itself is more efficient than passing a 
> reference to it. For large byte-size parameters, const and constref function 
> the same. The difference is with small byte-size parameters.

Hmmm I was told otherwise by one of the compiler devs and that I should use 
constref if I want to guarantee it will not be copied. Maybe one of them can 
confirm this….

 I tried to use https://godbolt.org/ but my program doesn’t seem to be 
producing any output...

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Adriaan van Os via fpc-devel

Hairy Pixels via fpc-devel wrote:



On Feb 1, 2023, at 5:56 PM, Adriaan van Os via fpc-devel 
 wrote:

"A const parameter is be passed by reference or (for small-sized parameters) by 
value, whatever is most efficient. A constref parameter is guaranteed to be passed by 
reference in all cases. The latter is therefore typically used for interfacing with 
external code or when writing assembler routines."


I’ve been confused by constref versus const. I use constref when passing large 
records as parameters so I know it will not make needless copies but why 
doesn’t const function this way too? If the parameter is constant why would it 
ever make sense for the compiler to copy the entire record when it knows the 
function can’t change it?


Because, if e.g. the byte-size of a parameter is such that it fits into a CPU register, then 
passing the parameter itself is more efficient than passing a reference to it. For large byte-size 
parameters, const and constref function the same. The difference is with small byte-size parameters.


Regards,

Adriaan van Os
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Hairy Pixels via fpc-devel


> On Feb 1, 2023, at 5:56 PM, Adriaan van Os via fpc-devel 
>  wrote:
> 
> "A const parameter is be passed by reference or (for small-sized parameters) 
> by value, whatever is most efficient. A constref parameter is guaranteed to 
> be passed by reference in all cases. The latter is therefore typically used 
> for interfacing with external code or when writing assembler routines."

I’ve been confused by constref versus const. I use constref when passing large 
records as parameters so I know it will not make needless copies but why 
doesn’t const function this way too? If the parameter is constant why would it 
ever make sense for the compiler to copy the entire record when it knows the 
function can’t change it?

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Bart via fpc-devel
On Wed, Feb 1, 2023 at 11:56 AM Adriaan van Os via fpc-devel
 wrote:

> That is wrong. It should read
>
> "A const parameter is be passed by reference or (for small-sized parameters) 
> by value, whatever is
> most efficient. A constref parameter is guaranteed to be passed by reference 
> in all cases. The
> latter is therefore typically used for interfacing with external code or when 
> writing assembler
> routines."
>
> In your case, constref is the right choice, although const would be fine also 
> (as your
> datastructure is larger than a small number of bytes).
>

Thank you.


-- 
Bart
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Question on constref

2023-02-01 Thread Adriaan van Os via fpc-devel

Bart via fpc-devel wrote:


"Note that in general, it should only be used for interfacing with
external code or when writing assembler routines."


That is wrong. It should read

"A const parameter is be passed by reference or (for small-sized parameters) by value, whatever is 
most efficient. A constref parameter is guaranteed to be passed by reference in all cases. The 
latter is therefore typically used for interfacing with external code or when writing assembler 
routines."


In your case, constref is the right choice, although const would be fine also (as your 
datastructure is larger than a small number of bytes).


Regards,

Adriaan van Os

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel