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 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 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 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 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 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 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 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 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 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 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 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 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


[fpc-devel] Question on constref

2023-02-01 Thread Bart via fpc-devel
Hi,

I have a function that has a parameter to a datastructure with some
arrays with records is it.
This function needs to return a pointer to a specific record inside
that structure.
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 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."

I therefore decided to make it a var parameter, but that feels a bit
odd since the function shall not ever alter the datastructure itself.
Hence my question: is it OK to use constref for a parameter (and is it
guaranteed to work by design this way) if I need to pas a parameter by
reference and the function/procedure shall not modify that parameter?

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

-- 
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 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 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 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