Pascal Viandier wrote:
I have to say, I understand your explanation but not the fundamental meaning of it. By inspecting the local variable with gdb, I see you are right. But since I declared the global string variable as a String(40), I expected the capacity passed to the procedure to be 40, not 3, which is the actual length, not the total string capacity . However, I think this is a rather strange behaviour. Why the original string capacity is not passed along with the value? In fact, this means the local string is not the same type as the one I declared globally and passed by value. Am I wrong?
That's right -- and that's a general property of value parameters. E.g., if you declare an integer subrange variable and pass it to an integer parameter (or vice versa), or an integer variable to a real parameter, or a char to a string parameter, the actual parameter will not have the same type as the formal parameter.
Indeed, in this case it's more surprising, but actually, the alternative would be surprising in even more subtle ways. Then, e.g., these two calls could produce different results:
var a: String (10);
procedure p (s: String); begin ... end;
begin a := 'foo'; p (a); p ('foo'); end.
This would clearly violate the properties of value parameters.
The procedure where I discovered this receives strings of various lengths then it pads them with blanks up to the length of the integer parameter and displays them in reverse video. The original value must not be modified, and it must accept even literals values. So, if I declare a type with a fixed length (capacity), I will not be able to pass strings of various lengths to my procedure anymore... I will go for the local copy solution for now, but I think it would have been a good idea to pass the capacity of the string instead of its actual length...
In this case, I'd recommend the local copy. You can declare the local variable as big as necessary, based on the integer parameter.
This will cause an additional string copy. But OTOH, you can then declare the string parameter `const' (as it will not be modified). This will save one string copy again (possibly modulo a GPC bug which will be fixed soon), so in the end you don't really lose speed, if that's a concern.
Actually, it's even better than passing the capacity, as this will work then (which wouldn't when passing the capacity):
var a: String (5);
begin a := 'foo'; p (a, 10); end.
In your case, it could only pad to 5 chars. With the local variable it can pad to 10 chars as I suppose it should.
Frank