It seems that const parameters of string types are passed by value, eg:
program peterT4;
type Str = String(1000);
var gs: Str;
procedure Doit( const s: Str ); begin if @s = @gs then begin WriteLn( 'OK' ); end else begin WriteLn( 'failed' ); end; end;
begin Doit( gs ); end.
fails.
I checked the code and it definitely looks like it is doing a copy.
I use a lot of long strings (2500) and so this seems like a serious problem to me...
Thanks, Peter.
On Tue, Jul 26, 2005 at 05:26:58PM +0800, Peter N Lewis wrote:
It seems that const parameters of string types are passed by value, eg:
program peterT4;
type Str = String(1000);
var gs: Str;
procedure Doit( const s: Str ); begin if @s = @gs then begin WriteLn( 'OK' ); end else begin WriteLn( 'failed' ); end; end;
begin Doit( gs ); end.
fails.
I checked the code and it definitely looks like it is doing a copy.
I use a lot of long strings (2500) and so this seems like a serious problem to me...
Thanks, Peter.
Const parameters may be passed by value or by reference at compiler's discretion. Use protected var to guarantee pass by reference.
Emil
Emil Jerabek wrote:
Peter N Lewis wrote:
It seems that const parameters of string types are passed by value, eg:
program peterT4;
type Str = String(1000);
var gs: Str;
procedure Doit( const s: Str ); begin if @s = @gs then begin WriteLn( 'OK' ); end else begin WriteLn( 'failed' ); end; end;
begin Doit( gs ); end.
fails.
I checked the code and it definitely looks like it is doing a copy.
I use a lot of long strings (2500) and so this seems like a serious problem to me...
Thanks, Peter.
Const parameters may be passed by value or by reference at compiler's discretion. Use protected var to guarantee pass by reference.
Or CONST VAR parameters, in next gpc release. Still - one would expect that gpc chooses the most efficient calling mechanism for each type, by value for small parameters and by reference for large parameters. In fact that is what gpc does for types other than strings (at least when I test it on Mac OS X).
Regards,
Adriaan van Os
At 11:49 +0200 26/7/05, Emil Jerabek wrote:
On Tue, Jul 26, 2005 at 05:26:58PM +0800, Peter N Lewis wrote:
It seems that const parameters of string types are passed by value, eg:
Const parameters may be passed by value or by reference at compiler's discretion. Use protected var to guarantee pass by reference.
I understand that, I just would expect gpc's discretion on how to pass a 1000 byte parameter would be by reference...
I am just in the process of converting fake long strings (record containing length and 2502 characters) used through my code to String(2502). The code after the conversion is much cleaner, and all the routines that are duplicated to handle either String or LongStringRecord can be reconciled. But if const s: String(2502) is going to take up 2502+ bytes on the stack and require a copy for each parameter, I'm going to have to consider either reverting this change or switching to "const var" everywhere. "protected var" is not very good for strings because you cannot then pass a constant string to it.
So is this considered a bug likely to be fixed in the near future, or is this considered a feature likely to be permanent?
I can convert all my use of "const" to "const var" when that support is released, so I guess that will resolve my problem, but it still seems wrong to me that the compiler would choose to pass strings by value...? Is there any compelling reason for const String() being passed by value?
Speaking of "const var", do we have an ETA for a version of the compiler with that support? Possible a new release with Waldek's changes and that support?
Thanks, Peter.
Peter N Lewis wrote:
At 11:49 +0200 26/7/05, Emil Jerabek wrote:
On Tue, Jul 26, 2005 at 05:26:58PM +0800, Peter N Lewis wrote:
It seems that const parameters of string types are passed by value, eg:
Const parameters may be passed by value or by reference at compiler's discretion. Use protected var to guarantee pass by reference.
I understand that, I just would expect gpc's discretion on how to pass a 1000 byte parameter would be by reference...
I am just in the process of converting fake long strings (record containing length and 2502 characters) used through my code to String(2502). The code after the conversion is much cleaner, and all the routines that are duplicated to handle either String or LongStringRecord can be reconciled. But if const s: String(2502) is going to take up 2502+ bytes on the stack and require a copy for each parameter, I'm going to have to consider either reverting this change or switching to "const var" everywhere. "protected var" is not very good for strings because you cannot then pass a constant string to it.
So is this considered a bug likely to be fixed in the near future, or is this considered a feature likely to be permanent?
The former. I notice that this case currently is "broken" with `const var' as well, so thanks for pointing me to this issue. I'll try to fix both cases before the next release.
BTW, unless you require the parameter to be limited to 1000 chars, you could simply declare it as `String'. This case works in GPC and it's usually more general (that's why I use it almost always, and therefore hadn't noticed the bug before).
Speaking of "const var", do we have an ETA for a version of the compiler with that support? Possible a new release with Waldek's changes and that support?
Yes, Waldek sent me a patch ready for integration. I'll have to finish some of my own changes. But first I'd like to re-install the web server, as putting a new release on a fully working server seems preferable ... ;-) I'll be off for a few days, so probably about 2 weeks ...
Frank
At 12:41 +0200 1/8/05, Frank Heckenbach wrote:
Peter N Lewis wrote:
On Tue, Jul 26, 2005 at 05:26:58PM +0800, Peter N Lewis wrote:
It seems that const parameters of string types are passed by
value, eg:
So is this considered a bug likely to be fixed in the near future, or is this considered a feature likely to be permanent?
The former. I notice that this case currently is "broken" with `const var' as well, so thanks for pointing me to this issue. I'll try to fix both cases before the next release.
Excellent.
BTW, unless you require the parameter to be limited to 1000 chars, you could simply declare it as `String'. This case works in GPC and it's usually more general (that's why I use it almost always, and therefore hadn't noticed the bug before).
I understand - I'm in the process of migrating, so I've first converted LongString from a record to String(2502). I now have lots of procedures in pairs like:
function IsExtension( const s: String ): Boolean; function LSIsExtension( const s: LongString ): Boolean;
It will take some time to migrate all of the code to just use String, but I'llg get there. In many cases, I've already changed LSIsExtension to just "return IsExtension( s )". I want to integrate some more changes from my team before I remove the procedures (it is already going to be a nightmare to integrate the changes, given the breadth of the change in making the switch from MW to GPC).
Thanks for the advice, Peter.