Re: [fpc-devel] Question on constref
> 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
> 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
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
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
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
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
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
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
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
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
> 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
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
> 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
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
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
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
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
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
> 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
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