hi This used to work:
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
Is it me or it? Russ
Russell Whitaker wrote:
This used to work:
... before GPC did range checking. ;-)
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
The length of the string is uninitalized (and probably happens to be 0), so accesss to characters > 0 (i.e., all ;-) is out-of range.
You could do `SetLength (s, 500)' before the loop, or `uses GPC; [...] s := StringOfChar (' ', 500);' instead of the loop.
Frank
Frank Heckenbach wrote:
Russell Whitaker wrote:
This used to work:
... before GPC did range checking. ;-)
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
The length of the string is uninitalized (and probably happens to be 0), so accesss to characters > 0 (i.e., all ;-) is out-of range.
You could do `SetLength (s, 500)' before the loop, or `uses GPC; [...] s := StringOfChar (' ', 500);' instead of the loop.
This certainly sounds like a semantics problem to me. I would normally expect to see the string extended by the writing action, with the range error based on the capacity. I see no easy answer that will be both secure and expected. Obviously there is automatic string initialization going on, and it sounds as if it is the simplest, i.e. the capacity and length. Maybe the StringOfChar(' ', length) should be called as part of the default initialization.
CBFalconer wrote:
Frank Heckenbach wrote:
Russell Whitaker wrote:
This used to work:
... before GPC did range checking. ;-)
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
The length of the string is uninitalized (and probably happens to be 0), so accesss to characters > 0 (i.e., all ;-) is out-of range.
You could do `SetLength (s, 500)' before the loop, or `uses GPC; [...] s := StringOfChar (' ', 500);' instead of the loop.
This certainly sounds like a semantics problem to me. I would normally expect to see the string extended by the writing action, with the range error based on the capacity.
While one might expect that, it isn't what ISO 10206 specifies as the semantics for an indexed-variable for a string-variable. From 6.5.3.2 Indexed-variables:
"For a string-variable in an indexed-variable, the index-expression of the indexed-variable shall possess the integer-type, and it shall be an error if the value of the index-expression is not in the index-domain of the value of the string-variable. It shall be an error to alter the length of the value of a string-variable when a reference to a component of the string-variable exists. It shall be an error to access an indexed-variable when the string-variable, if any, of the indexed-variable is undefined."
And from 6.4.3.3.1 General (String Types):
"The length of a string-type value shall be the number of members in its index-domain. The string- type value with length zero is designated the null-string."
Given these requirements:
1. The original program is in error since it is indexing an undefined string-variable.
2. One cannot extend the length of schema string up to the capacity through indexing since it is an error to use an index that isn't within the index-domain of the string-variable and by definition the index-domain is either null or limited to the range corresponding to the string length number of members.
... I see no easy answer that will be both secure and expected. Obviously there is automatic string initialization going on, and it sounds as if it is the simplest, i.e. the capacity and length. Maybe the StringOfChar(' ', length) should be called as part of the default initialization.
The easy, ISO 10206 standard answer to initialize a large capacity string to all spaces is to use the writestr procedure. Given the original program's declaration for string "s":
writestr(s,' ':500);
(or more generalized: writestr(s,' ':s.capacity);)
will initialize string "s" to 500 space characters and "s" will have a length of 500 suitable for subsequent single element indexing or substring indexing.
I'll note that even if one wants to initialize a large string to something other than space characters in a standard conformant manner, you can still use the statement to put the string into a defined state so that you can legally access all string elements (up to the string capacity) using single element indexing or substring indexing.
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
... snip explanations ...
I'll note that even if one wants to initialize a large string to something other than space characters in a standard conformant manner, you can still use the statement to put the string into a defined state so that you can legally access all string elements (up to the string capacity) using single element indexing or substring indexing.
Thanks, that all makes sense.
CBFalconer wrote:
Frank Heckenbach wrote:
Russell Whitaker wrote:
This used to work:
... before GPC did range checking. ;-)
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
The length of the string is uninitalized (and probably happens to be 0), so accesss to characters > 0 (i.e., all ;-) is out-of range.
You could do `SetLength (s, 500)' before the loop, or `uses GPC; [...] s := StringOfChar (' ', 500);' instead of the loop.
This certainly sounds like a semantics problem to me. I would normally expect to see the string extended by the writing action, with the range error based on the capacity. I see no easy answer that will be both secure and expected. Obviously there is automatic string initialization going on, and it sounds as if it is the simplest, i.e. the capacity and length.
No, it isn't. As I wrote, the length is uninitialized (i.e., undefined). It usually *happens* to be 0 for a global variable, and GPC doesn't check for undefined values.
The capacity, OTOH, is initialized, and must be in order for the string to work at all.
Maybe the StringOfChar(' ', length) should be called as part of the default initialization.
I don't think so. This can be quite some effort, which is not normally wanted. If you assign a string of length 3 to this variable, it needs to set the length and 3 char fields. Blanking the remaining 497 fields is just unnecessary work, unless the programmer has very special needs, but that's not the default.
Frank
On Sun, 7 Aug 2005, Frank Heckenbach wrote:
CBFalconer wrote:
Frank Heckenbach wrote:
Russell Whitaker wrote:
This used to work:
... before GPC did range checking. ;-)
program fil; var i : integer; s : string( 500 ); begin for i := 1 to 500 do s[ i ] := ' '; writeln("ok"); end.
Now I get "Value out of range"
The length of the string is uninitalized (and probably happens to be 0), so accesss to characters > 0 (i.e., all ;-) is out-of range.
You could do `SetLength (s, 500)' before the loop, or `uses GPC; [...] s := StringOfChar (' ', 500);' instead of the loop.
This certainly sounds like a semantics problem to me. I would normally expect to see the string extended by the writing action, with the range error based on the capacity. I see no easy answer that will be both secure and expected. Obviously there is automatic string initialization going on, and it sounds as if it is the simplest, i.e. the capacity and length.
No, it isn't. As I wrote, the length is uninitialized (i.e., undefined). It usually *happens* to be 0 for a global variable, and GPC doesn't check for undefined values.
The capacity, OTOH, is initialized, and must be in order for the string to work at all.
Would it be reasonable to define the length to be 0 as the default initialization? Otherwise the following should produce an error but dosen't:
program foo; var s : string( 500 ); begin writeln( length(s) ); end.
As for the original problem, many thanks to Frank, Chuck F, HF, and Gale Paeper for their help.
Russ
Russell Whitaker wrote:
The capacity, OTOH, is initialized, and must be in order for the string to work at all.
Would it be reasonable to define the length to be 0 as the default initialization?
It would be nonstandard. Basically the same question as defining default values for other types. The programmer can do this explicitly (String (n) value '') if wanted.
Otherwise the following should produce an error but dosen't:
program foo; var s : string( 500 ); begin writeln( length(s) ); end.
As I said, GPC doesn't check for using undefined values at all. (Currently, and this isn't going to change soon, as this is not exactly trivial to implement in general ...)
Frank