Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2008-10

Question: range checking for string indexing

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Tom Verhoeff

Can someone confirm what range checking FreePascal does (if enabled) when indexing a string. I imagine shortstrings and ansistrings are handled differently, but cannot find this in the documentation.

It looks like the following:

String Type Range Checked for s[i]
----------- ----------------------
s: ShortString 0 <= i <= 255
s: AnsiString 1 <= i <= Length(s)

I am surprised that for ShortString, the range is not also 1 <= i <= Length(s).

IIRC Turbo Pascal only allowed you to access s[0] when range checking was off, and similarly for s[i] with i > Length(s).

Thanks,

Tom

E-MAIL: T.Verhoeff @ TUE.NL | Dept. of Math. & Comp. Science PHONE: +31 40 247 41 25 | Technische Universiteit Eindhoven FAX: +31 40 247 54 04 | PO Box 513, NL-5600 MB Eindhoven http://www.win.tue.nl/~wstomv/ | The Netherlands
Vinzent Höfler
to Tom Verhoeff
Tom Verhoeff wrote 5 lines
I am surprised that for ShortString, the range is not also 1 <= i <= Length(s). IIRC Turbo Pascal only allowed you to access s[0] when range checking was off, and similarly for s[i] with i > Length(s).

No. See transcript:

-- 8< -- the program --
{$R+}
var
    s1 : String;
    s2 : String[40];
begin
   s1 := '';
   s2 := '';
   WriteLn (Length (s1));
   WriteLn (Length (s2));
   WriteLn (Ord (s1[0]));
   WriteLn (Ord (s2[0]));
   WriteLn (Ord (s1[255]));
   WriteLn (Ord (s2[255]));
end.
-- 8< --

results in:

-- 8< --
Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland International TEST.PAS(18): Error 76: Constant out of range.

   WriteLn (Ord (s2[255]));
                       ^

-- 8< --

Commenting out the offending last line of code:

-- 8< --
Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland International TEST.PAS(19)
19 lines, 2432 bytes code, 968 bytes data.
-- 8< --

Running the program:

-- 8< --
.\TEST.EXE
0
0
0
0
0
-- 8< --

No errors, although the index exceeds the actual length of the string.

Vinzent.

Tom Verhoeff
to Vinzent Höfler
Vinzent Höfler wrote 9 lines
Tom Verhoeff wrote: > I am surprised that for ShortString, the range is not > also 1 <= i <= Length(s). > > IIRC Turbo Pascal only allowed you to access s[0] when range checking > was off, and similarly for s[i] with i > Length(s). No. See transcript:

That looks rather convincing.

Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland International

However, IIRC there were some differences between Borland Pascal and Turbo Pascal (as it was named before they marketed it as Borland Pascal).

But my memory may be confusing this with UCSD Pascal (Oh, those days :-).

If find it more important that the rules are clear, than that a specific behavior is provided.

Nevertheless, this means that AnsiStrings and ShortStrings are slightly more different than suggested in the documentation. AnsiString provide more protection with range checking (also implying that a program that works will with range checking and ShortStrings, might fail when using AnsiStrings, even though those are more flexible).

In what way can this information be incorporated into the documentation? Where should it go? Can I generate a patch for that?

Thanks,

Tom

E-MAIL: T.Verhoeff @ TUE.NL | Dept. of Math. & Comp. Science PHONE: +31 40 247 41 25 | Technische Universiteit Eindhoven FAX: +31 40 247 54 04 | PO Box 513, NL-5600 MB Eindhoven http://www.win.tue.nl/~wstomv/ | The Netherlands
Frank Peelo
to Tom Verhoeff
Tom Verhoeff wrote 23 lines
On Wed, Oct 29, 2008 at 09:58:10PM +0100, Vinzent Höfler wrote: >Tom Verhoeff wrote: > > >>I am surprised that for ShortString, the range is not >>also 1 <= i <= Length(s). >> >>IIRC Turbo Pascal only allowed you to access s[0] when range checking >>was off, and similarly for s[i] with i > Length(s). > >No. See transcript: That looks rather convincing. >Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland International However, IIRC there were some differences between Borland Pascal and Turbo Pascal (as it was named before they marketed it as Borland Pascal).

IIRC the differences were in how big a program you could write. Accessing the length byte in a string did not change.

[digs out an old copy of Turbo.com -- TurboPascal version 3. Amazingly, it will run under WinXP.]

var
   x : String[50];
   i : Integer;
Begin
   x := 'Hello, World';
   for i := 0 to length(x) do
     write(ord(x[i]),' ');
   writeln;
   x[0] := #5;
   writeln(x);
end.

Outputs this:
12 72 101 108 108 111 44 32 87 111 114 108 100
Hello

so read and write access to element 0

Vinzent Höfler
to Tom Verhoeff: That looks rather convincing. However, IIRC there were some differences between Borland…
Tom Verhoeff wrote 17 lines
On Wed, Oct 29, 2008 at 09:58:10PM +0100, Vinzent Höfler wrote: > Tom Verhoeff wrote: > >> I am surprised that for ShortString, the range is not >> also 1 <= i <= Length(s). >> >> IIRC Turbo Pascal only allowed you to access s[0] when range checking >> was off, and similarly for s[i] with i > Length(s). > No. See transcript: That looks rather convincing. > Borland Pascal Version 7.0 Copyright (c) 1983,92 Borland International However, IIRC there were some differences between Borland Pascal and Turbo Pascal (as it was named before they marketed it as Borland Pascal).

Yes, there were. But regarding string handling, nothing changed, at least not between TP5.5 and BP7. And I know for sure that accessing element 0 was always allowed, because it could be taken as shortcut for reading or even changing the length.

Nevertheless, this means that AnsiStrings and ShortStrings are slightly more different than suggested in the documentation.

Well, if you put it this way, yes. With ShortStrings you rather get a maximum size (where indexing is allowed regardless of the actual length, although the behaviour could be considered more or less undefined - just like accessing uninitialized memory), whilst AnsiString's behaviour doesn't distinguish between length and (maximum) size.

Vinzent.