Interesting. However, I wonder if this truncation is valid. Looking at ISO-10206, it states in section <6.4.6 Assignment-compatibility> :
"At any place where the rule of assignment-compatibility is used ... c) it shall be an error if T1 and T2 are compatible, T1 is a string-type or the char-type, and the length of the value of T2 is greater than the capacity of T1;"
My interpretation of this, is that in this situation, the statement AString:=AString+'ML' should have resulted in an error, since the compiler only allocated a capacity of 1 to AString, yet such a concatenation can never fit within this capacity.
Joe.
-----Original Message----- From: Frank Heckenbach [SMTP:frank@g-n-u.de] Sent: Monday, March 18, 2002 8:42 AM To: gpc@gnu.de Subject: Re: Problem with gpc 2.1 RC 3
Prof Abimbola Olowofoyeku wrote:
On 17 Mar 2002 at 13:16, Martin Liddle wrote:
I have just moved to RC 3. Looking at the list of fixed bugs it is obvious that a lot of work has been done in the last few months;
thanks
to all concerned. The stricter type checking required a lot of effort to get our code to compile but in fairness did highlight a number of problems in our code; so I think it was time well spent. However I am now stuck because of the following problem:
Program WriteTest;
Procedure ZWriteln(AString:String); Begin AString:=AString+'ML'; Writeln('String [',AString,'] Length is ',Length(AString)); End;
Begin ZWriteln(' '); End.
What I see is that length is reported as 1 i.e. the string
concatenation
is failing. Is this expected behaviour or a bug?
It is a bug alright. If you pass a string variable rather than a literal to 'ZWriteln', the concatentation is successful. So, something seems to have gone awry somewhere.
No, it's not a bug. `AString' is a formal parameter of undiscriminated schema type. This means it assumes the discriminants (in case of String: Capacity) of the actual parameter. In the example, the actual parameter is a string constant of length 1. It also has capacity 1, since constants can't change, anyway.
So also the parameter has capacity 1 during the execution of `ZWriteln'. Assigning ` ML' (the result of concatenation) to a capacity 1 string results in truncation to ` '. This behaviour is not new, BTW.
------ snip ------
On 18 Mar 2002 at 18:46, da Silva, Joe wrote:
Interesting. However, I wonder if this truncation is valid. Looking at ISO-10206, it states in section <6.4.6 Assignment-compatibility> :
"At any place where the rule of assignment-compatibility is used ... c) it shall be an error if T1 and T2 are compatible, T1 is a string-type or the char-type, and the length of the value of T2 is greater than the capacity of T1;"
My interpretation of this, is that in this situation, the statement AString:=AString+'ML' should have resulted in an error, since the compiler only allocated a capacity of 1 to AString, yet such a concatenation can never fit within this capacity.
Perhaps in EP mode, it should generate an error. In other modes, it should [a] at least generate a warning, or, [b] (and perhaps more controversially), treat string literals of < 255 chars as strings of 255 capacity. The first seems to be the better of the two, but perhaps generating an error in all modes is the best solution.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~African_Chief email: African_Chief@bigfoot.com
Prof Abimbola Olowofoyeku wrote:
On 18 Mar 2002 at 18:46, da Silva, Joe wrote:
Interesting. However, I wonder if this truncation is valid. Looking at ISO-10206, it states in section <6.4.6 Assignment-compatibility> :
"At any place where the rule of assignment-compatibility is used ... c) it shall be an error if T1 and T2 are compatible, T1 is a string-type or the char-type, and the length of the value of T2 is greater than the capacity of T1;"
My interpretation of this, is that in this situation, the statement AString:=AString+'ML' should have resulted in an error, since the compiler only allocated a capacity of 1 to AString, yet such a concatenation can never fit within this capacity.
: 3.2 Error : : A violation by a program of the requirements of this International Standard : that a processor is permitted to leave undetected.
;-)
Maybe we'll add such a check sometime ...
Perhaps in EP mode, it should generate an error. In other modes, it should [a] at least generate a warning,
Warnings only exist at compile-time. That's more difficult (the compiler would have to analyze the minimum length of the concatenation) that at runtime. Ideally, it should do both ...
or, [b] (and perhaps more controversially), treat string literals of < 255 chars as strings of 255 capacity.
No, why? For BP compatibility, it should be enough to treat `String' as `String[255]' (which GPC currently does only in contexts where an undiscriminated `String' normally makes no sense, but I think we already discussed a switch) ...
Frank
On 23 Mar 2002 at 5:12, Frank Heckenbach wrote:
[...]
Perhaps in EP mode, it should generate an error. In other modes, it should [a] at least generate a warning,
Warnings only exist at compile-time. That's more difficult (the compiler would have to analyze the minimum length of the concatenation) that at runtime. Ideally, it should do both ...
Well, at least it can generate an error. But see below ...
or, [b] (and perhaps more controversially), treat string literals of < 255 chars as strings of 255 capacity.
No, why? For BP compatibility, it should be enough to treat `String' as `String[255]'
It isn't enough. Try this program;
program testfoo; procedure foo (s : string); begin writeln (sizeof (s)); end; procedure bar (const s: string); begin writeln (sizeof (s)); end; begin foo ('Frank'); bar ('Chief'); end.
In GPC, it prints '16', '16'. In BP, it prints '256', '256'. Similarly with TMT Pascal. With compilers that have AnsiStrings (Delphi, Virtual Pascal) it prints '256', '256', unless you compile with {$H+} (i.e., in "AnsiString" or "Long String" mode), in which case it prints '4', '4' (AnsiStrings are internally pointers).
So you can see that GPC, on this issue, is entirely in a class of its own (i.e., not compatible with any other Pascal compiler in any respect - and certainly not with BP).
(which GPC currently does only in contexts where an undiscriminated `String' normally makes no sense, but I think we >already discussed a switch) ...
We did. Maybe it's time to consider implementing it? Perhaps we could accept "{$H-}" and something like "--short-strings" or "--BP-strings" to treat undiscriminated strings - function results, variables, record/object fields, and string literals, as BP strings, and without any warnings too. The default could be "{$H+}" or "--long-strings", which, at present would simply mean exactly what we have now (i.e., warnings, etc.) - or we (more controversially) could even treat undiscriminated strings in {$H+} mode as errors and refuse them at compile time. I am not all sure that all or any of this is a good idea. I just want to generate some discussion on the issue.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~African_Chief email: African_Chief@bigfoot.com
Prof Abimbola Olowofoyeku wrote:
or, [b] (and perhaps more controversially), treat string literals of < 255 chars as strings of 255 capacity.
No, why? For BP compatibility, it should be enough to treat `String' as `String[255]'
It isn't enough.
Yes, it is. As I said, GPC currently does *not* do so in all contexts yet.
In GPC, it prints '16', '16'. In BP, it prints '256', '256'. Similarly with TMT Pascal. With compilers that have AnsiStrings (Delphi, Virtual Pascal) it prints '256', '256', unless you compile with {$H+} (i.e., in "AnsiString" or "Long String" mode), in which case it prints '4', '4' (AnsiStrings are internally pointers).
So you can see that GPC, on this issue, is entirely in a class of its own (i.e., not compatible with any other Pascal compiler in any respect
- and certainly not with BP).
Come on, please! First of all, comparing `SizeOf' is not a good idea because it depends too much on the internal structure. Secondly, what exactly do you mean with "any other Pascal compiler"? AFAICS, you only compared GPC's standard conformant behaviour to three nonstandard compilers (which are all modelled after each other, so the fact that they behave the same doesn't tell much about whether that's a good behaviour). Any EP conformant compiler will behave like GPC does (except that `SizeOf' is nonstandard itself, but one can see it, e.g., testing the Capacity).
(which GPC currently does only in contexts where an undiscriminated `String' normally makes no sense, but I think we >already discussed a switch) ...
We did. Maybe it's time to consider implementing it?
If you like to do it, just go ahead. :-)
Perhaps we could accept "{$H-}" and something like "--short-strings" or "--BP-strings" to treat undiscriminated strings - function results, variables, record/object fields, and string literals, as BP strings, and without any warnings too. The default could be "{$H+}" or "--long-strings", which, at present would simply mean exactly what we have now (i.e., warnings, etc.) - or we (more controversially) could even treat undiscriminated strings in {$H+} mode as errors and refuse them at compile time.
You mean variables (not parameters), I assume, i.e. turning the current warnings into errors. Yes, this might be reasonable then.
Frank
On 23 Mar 2002 at 15:35, Frank Heckenbach wrote:
[...]
No, why? For BP compatibility, it should be enough to treat `String' as `String[255]'
It isn't enough.
Yes, it is. As I said, GPC currently does *not* do so in all contexts yet.
Maybe this is just a question of words and meanings - but I think you just said that it is not enough ;-). I guess it all depends then on what one means by "enough".
In GPC, it prints '16', '16'. In BP, it prints '256', '256'. Similarly with TMT Pascal. With compilers that have AnsiStrings (Delphi, Virtual Pascal) it prints '256', '256', unless you compile with {$H+} (i.e., in "AnsiString" or "Long String" mode), in which case it prints '4', '4' (AnsiStrings are internally pointers).
So you can see that GPC, on this issue, is entirely in a class of its own (i.e., not compatible with any other Pascal compiler in any respect - and certainly not with BP).
Come on, please! First of all, comparing `SizeOf' is not a good idea because it depends too much on the internal structure.
Of course. It is simply to illustrate that BP (and compatible compilers) treat a string literal passed as a parameter as a 255 character string. The best comparison would be 'Capacity' and not 'Sizeof' - but of course 'Capacity' does not exist on BP or Delphi.
Secondly, what exactly do you mean with "any other Pascal compiler"?
The ones I just referred to.
AFAICS, you only compared GPC's standard conformant behaviour to three nonstandard compilers (which are all modelled after each other, so the fact that they behave the same doesn't tell much about whether that's a good behaviour). Any EP conformant compiler will behave like GPC does (except that `SizeOf' is nonstandard itself, but one can see it, e.g., testing the Capacity).
We were talking about BP string compatibility.
(which GPC currently does only in contexts where an undiscriminated `String' normally makes no sense, but I think we
already discussed a switch) ...
We did. Maybe it's time to consider implementing it?
If you like to do it, just go ahead. :-)
If I knew how to, I would have done it long ago ;). Unfortunately, very few people actually know how to hack the GPC compiler. If I tried to hack it, what you would get would not be worthy of the title "compiler" (that is, even it it managed to compile in the first place).
Perhaps we could accept "{$H-}" and something like "--short-strings" or "--BP-strings" to treat undiscriminated strings - function results, variables, record/object fields, and string literals, as BP strings, and without any warnings too. The default could be "{$H+}" or "--long-strings", which, at present would simply mean exactly what we have now (i.e., warnings, etc.) - or we (more controversially) could even treat undiscriminated strings in {$H+} mode as errors and refuse them at compile time.
You mean variables (not parameters), I assume, i.e. turning the current warnings into errors.
Yes.
Yes, this might be reasonable then.
We are agreed on one thing then! :-)
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~African_Chief email: African_Chief@bigfoot.com
Prof Abimbola Olowofoyeku wrote:
On 23 Mar 2002 at 15:35, Frank Heckenbach wrote:
[...]
No, why? For BP compatibility, it should be enough to treat `String' as `String[255]'
It isn't enough.
Yes, it is. As I said, GPC currently does *not* do so in all contexts yet.
Maybe this is just a question of words and meanings - but I think you just said that it is not enough ;-).
Did I? How should I have expressed better that I didn't mean this? (Unfortunately, there doesn't be an English translation of the German word "doch". ;-)
Anyway, I meant that it is enough to treat `String' as `String[255]' (which GPC does not yet always do).
So you can see that GPC, on this issue, is entirely in a class of its own (i.e., not compatible with any other Pascal compiler in any respect - and certainly not with BP).
Come on, please! First of all, comparing `SizeOf' is not a good idea because it depends too much on the internal structure.
Of course. It is simply to illustrate that BP (and compatible compilers) treat a string literal passed as a parameter as a 255 character string.
They don't do anything special with string literals. The difference is that they interpret `String' in the formal parameter (and elsewhere) as `String[255]' while GPC interprets it as an undiscriminated string (which BP & Co. don't have).
Secondly, what exactly do you mean with "any other Pascal compiler"?
The ones I just referred to.
Which are certainly not any other Pascal compilers.
AFAICS, you only compared GPC's standard conformant behaviour to three nonstandard compilers (which are all modelled after each other, so the fact that they behave the same doesn't tell much about whether that's a good behaviour). Any EP conformant compiler will behave like GPC does (except that `SizeOf' is nonstandard itself, but one can see it, e.g., testing the Capacity).
We were talking about BP string compatibility.
Then I guess what you meant to say is that BP and compatibles are a class of their own, and you'd like GPC to emulate their non-standard behaviour. ;-)
In generally, I have agreed that we should add this feature (via the switch). However, I don't consider it as important as many other things to do, so the chances that I will do it soon are rather small ...
Frank
On 24 Mar 2002 at 1:08, Frank Heckenbach wrote:
[...]
Yes, it is. As I said, GPC currently does *not* do so in all contexts yet.
Maybe this is just a question of words and meanings - but I think you just said that it is not enough ;-).
Did I? How should I have expressed better that I didn't mean this?
Don't worry. What you *meant* was expressed as clearly as it could be. I was just insinuating that the fact that GPC does so in some contexts, while it doesn't do so in some other contexts (which can then lead to hidden or obscure errors in programs) indicates that what GPC does is perhaps not "enough". This is of course a matter of opinion and interpretation, and I accept that being 100% BP compatible in this respect is not a priority. But at the very least, this issue should be documented - or GPC should generate an error (so that the programmer will not assume that the code is going to work correctly). I think we are agreed already that this is a good idea - so I guess the discussion is now redundant.
(Unfortunately, there doesn't be an English translation of the German word "doch". ;-)
Anyway, I meant that it is enough to treat `String' as `String[255]' (which GPC does not yet always do).
Yes. See above.
[...]
Secondly, what exactly do you mean with "any other Pascal compiler"?
The ones I just referred to.
Which are certainly not any other Pascal compilers.
My mistake. What I should have said was "any other compiler that is BP- compatible". I guess my intended meaning is clear now?
[...]
We were talking about BP string compatibility.
Then I guess what you meant to say is that BP and compatibles are a class of their own,
Certainly. And we are trying to emulate that class.
and you'd like GPC to emulate their non-standard behaviour. ;-)
No, it does not make any difference to me, because I have long ago come to terms with the subtle differences. However, others may not have done so, and newbies to GPC will certainly not have. They will then have problems, and will come here to talk about it. Then another discussion of this type may ensue. This can reoccur again and again. We might all end up being grandfathers, and still be answering this question ;-). This is why I am suggesting that we should do something about it.
In generally, I have agreed that we should add this feature (via the switch). However, I don't consider it as important as many other things to do, so the chances that I will do it soon are rather small ...
Fair enough. But can you at least generate an error or add this to the FAQ (i.e., if it is not there already?).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~African_Chief email: African_Chief@bigfoot.com
Prof Abimbola Olowofoyeku wrote:
Don't worry. What you *meant* was expressed as clearly as it could be. I was just insinuating that the fact that GPC does so in some contexts, while it doesn't do so in some other contexts (which can then lead to hidden or obscure errors in programs) indicates that what GPC does is perhaps not "enough".
I agree.
This is of course a matter of opinion and interpretation, and I accept that being 100% BP compatible in this respect is not a priority. But at the very least, this issue should be documented - or GPC should generate an error
Finding the places where to put the errors is already half the job required to implement the BP compatible behaviour. (What GPC does now is in places where otherwise an error would be produces, but now we're talking about places which are valid already, but should get a new meaning. Though I can roughly imagine where to look for those places, it would require some amount of testing to make sure I don't miss anything or change the behaviour in cases where it shouldn't. I'm reluctant to do this now, shortly before a release.)
No, it does not make any difference to me, because I have long ago come to terms with the subtle differences. However, others may not have done so, and newbies to GPC will certainly not have. They will then have problems, and will come here to talk about it. Then another discussion of this type may ensue. This can reoccur again and again. We might all end up being grandfathers, and still be answering this question ;-). This is why I am suggesting that we should do something about it.
Unfortunately I think there are some more issues (range checking, qualified identifiers, ...) that the same would apply to.
In generally, I have agreed that we should add this feature (via the switch). However, I don't consider it as important as many other things to do, so the chances that I will do it soon are rather small ...
Fair enough. But can you at least generate an error or add this to the FAQ (i.e., if it is not there already?).
I didn't see it there. Perhaps you might want to write a suggested wording for the FAQ.
Frank
On 2 Apr 2002 at 1:30, Frank Heckenbach wrote:
[...]
Fair enough. But can you at least generate an error or add this to the FAQ (i.e., if it is not there already?).
I didn't see it there. Perhaps you might want to write a suggested wording for the FAQ.
What about something like this:
Q. Any "gotchas"?
A. Be careful when passing string literals as parameters to routines accepting the string as a value parameter and that internally modify the value of the parameter. Inside the routine, the value parameter gets a fixed Capacity - the length of the string literal that was passed to it. Any attempt to assign a longer value will not work.
Best regards, The Chief --------- Prof. Abimbola Olowofoyeku (The African Chief) Email: African_Chief@bigfoot.com http://www.bigfoot.com/~african_chief/
Prof. A Olowofoyeku (The African Chief) wrote:
On 2 Apr 2002 at 1:30, Frank Heckenbach wrote:
[...]
Fair enough. But can you at least generate an error or add this to the FAQ (i.e., if it is not there already?).
I didn't see it there. Perhaps you might want to write a suggested wording for the FAQ.
What about something like this:
Q. Any "gotchas"?
A. Be careful when passing string literals as parameters to routines accepting the string as a value parameter and that internally modify the value of the parameter. Inside the routine, the value parameter gets a fixed Capacity - the length of the string literal that was passed to it. Any attempt to assign a longer value will not work.
OK. I'm adding:
This only applies if the value parameter is declared as @samp{String}. If it is declared as a string with a given capacity (e.g., @samp{String (255)}), it gets this capacity within the routine.
Frank
In article 3CA99056.25733.38E4CF@localhost, "Prof. A Olowofoyeku (The African Chief)" african_chief@bigfoot.com writes
What about something like this:
Q. Any "gotchas"?
A. Be careful when passing string literals as parameters to routines accepting the string as a value parameter and that internally modify the value of the parameter. Inside the routine, the value parameter gets a fixed Capacity - the length of the string literal that was passed to it. Any attempt to assign a longer value will not work.
Sounds pretty good to me. I'd change the wording of the last sentence to read "Any attempt to increase the length of the string will fail."
Martin Liddle wrote:
In article 3CA99056.25733.38E4CF@localhost, "Prof. A Olowofoyeku (The African Chief)" african_chief@bigfoot.com writes
What about something like this:
Q. Any "gotchas"?
A. Be careful when passing string literals as parameters to routines accepting the string as a value parameter and that internally modify the value of the parameter. Inside the routine, the value parameter gets a fixed Capacity - the length of the string literal that was passed to it. Any attempt to assign a longer value will not work.
Sounds pretty good to me. I'd change the wording of the last sentence to read "Any attempt to increase the length of the string will fail."
Actually, I think I prefer the Chief's wording. The latter might make people think of `SetLength' etc., while assigning is the most common way of changing strings.
Frank