Recent

Author Topic: [Solved] Relationship between high(ashortstring) and length(ashortstring)  (Read 7155 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Hello.

This is a question asked in Spanish forum but we (I) dont get the logical.
https://forum.lazarus.freepascal.org/index.php/topic,60504.msg452955.html#msg452955

With this:

Code: Pascal  [Select][+][-]
  1. program cadena;
  2. {$mode objfpc}{$H-}  // Alias String is ShortString
  3. var
  4.   Frase: String;
  5. begin
  6.   Frase := 'Esto es una prueba';
  7.   WriteLn(low(Frase));
  8.   WriteLn(High(Frase));
  9.   WriteLn(Length(Frase));
  10.   Readln()
  11. end.
  12.  

This is the result:
Code: Bash  [Select][+][-]
  1. fred@fred-80m0 ~> ./cadena
  2. 0
  3. 255
  4. 18

Why High(Frase) = 255 (and not Length(Frase) - 1) ?
« Last Edit: September 10, 2022, 06:27:20 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #1 on: September 10, 2022, 03:56:06 pm »
Length() used on a string gives back its size in chars.
Low() and High() give back start and end position for an array.

In your case the string is optimized by compiler to a shortstring.

Reading definition for https://wiki.lazarus.freepascal.org/Shortstring shows me:
Quote
Warning: low(myShortString) returns 0, i. e. the index of the length Byte, not the first character’s index. Likewise, high(myShortString) always returns 255. Use length instead.

I hope this helps the spanish forum  :-*
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #2 on: September 10, 2022, 04:00:57 pm »
Quote
Warning: ... Likewise, high(myShortString) always returns 255. Use length instead.

Ha, ok, hidden in the bottom, many thanks for the light.
(But, imho, a few exotic to do so, anyway, understood now.)
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #3 on: September 10, 2022, 04:05:31 pm »
confuse them yet better :-)

Quote
program cadena;
{$mode objfpc}{$H+}  // Alias String is AnsiString
var
  Frase: String[100];
begin
  Frase := 'Esto es una prueba';
  WriteLn(low(Frase));
  WriteLn(High(Frase));
  WriteLn(Length(Frase));
  Readln()
end.

Kays

  • Hero Member
  • *****
  • Posts: 618
  • Whasup!?
    • KaiBurghardt.de
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #4 on: September 10, 2022, 04:15:17 pm »
Low() and High() give back start and end position for an array.
I concur. Any index in the range low(T)..high(T) is valid insofar it will not cause a memory access violation. It doesn’t mean the component at high(T) will be meaningful (has been initialized). To get meaningful content from a shortString use the range 1..length(T) as index.
Yours Sincerely
Kai Burghardt

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #5 on: September 10, 2022, 04:18:16 pm »
confuse them yet better :-)

Quote
program cadena;
{$mode objfpc}{$H+}  // Alias String is AnsiString
var
  Frase: String[100];
begin
  Frase := 'Esto es una prueba';
  WriteLn(low(Frase));
  WriteLn(High(Frase));
  WriteLn(Length(Frase));
  Readln()
end.

And with shortstring:
 
Code: Pascal  [Select][+][-]
  1.  program cadena;
  2. {$mode objfpc}{$H-} // shortstring
  3. var
  4.     Frase: String[100];
  5. begin
  6.   Frase := 'Esto es una prueba';
  7.   WriteLn(low(Frase));
  8.   WriteLn(High(Frase));
  9.   WriteLn(Length(Frase));
  10.   Readln()
  11. end.
  12.  

--->

Code: Bash  [Select][+][-]
  1. fred@fred-80m0 ~> ./cadena
  2. 0
  3. 100
  4. 18


Ha, yes, indeed, more confusion. ( in doc: Likewise, high(myShortString) always returns 255.)
« Last Edit: September 10, 2022, 05:11:01 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

MarkMLl

  • Hero Member
  • *****
  • Posts: 8453
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #6 on: September 10, 2022, 04:24:04 pm »
Low() and High() give back start and end position for an array.
I concur. Any index in the range low(T)..high(T) is valid insofar it will not cause a memory access violation. It doesn’t mean the component at high(T) will be meaningful (has been initialized). To get meaningful content from a shortString use the range 1..length(T) as index.

To emphasise that: irrespective of what Low() might return, in the case of a string any reference to element [ 0 ] should be treated as an error or- at the very least- extremely ill-advised.

Similarly, and leaving aside encoding problems caused by UTF-8 etc., any reference to an element beyond [ Length() ] should be treated as extremely ill-advised, since it is possible that a string implementation that allocates memory in chunks could return a misleading High().

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #7 on: September 10, 2022, 04:33:25 pm »
confuse them yet better :-)

Quote
program cadena;
{$mode objfpc}{$H+}  // Alias String is AnsiString

Oops, I did not see that you changed with ansisstring, the problem is mainly with shortstring (ansistring is understood).
Anyway your example gives confusion also.
See my previous post edited.
« Last Edit: September 10, 2022, 04:41:34 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #8 on: September 10, 2022, 04:46:02 pm »
There is no confusion for people who remember 16-bit TuboPascal and Delphi 1.x - those did not have LongStrings, and did not needed them very much indeed.

Basically it is the same history that makes LongString (as those types of string are together called in Delphi RTL internals) first letter by s[1] while dynarrays start with a[0]

Actually it was AnsiString introduced that made a lot of confusion then. Suddenyly SizeOf(s) started showing wrong results. Suyddenly s[0] := #13 did not more change string's length, etc.
Frankly, i'd like every programmer read about ShortStrings mandatoriy, because without knowing that history you indeed can not grasp why dynarrays and long strings differ and has to memorize without understanding.

Oh, and more coans.

Code: Pascal  [Select][+][-]
  1. var w: WideString; a: AnsiString;
  2. begin
  3.     a := '1234';  w := a;  // the same value, right ?
  4.     WriteLn( SizeOf(a[1]): 10, SizeOf(a): 10);   // expected, right?
  5.     WriteLn( SizeOf(w[1]): 10, SizeOf(w): 10);  // did it scale well ?
  6. end;
  7.  

Ooops, that was for 32-bit code. For you it has to be a := '12345678';  w := a;

When you grasp that history it all is obvious and expected. When you had some experience with that 16-bits programminf - yet better.
« Last Edit: September 10, 2022, 04:54:15 pm by Arioch »

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #9 on: September 10, 2022, 04:47:33 pm »
Ha, yes, indeed, more confusion. ( in doc: Likewise, high(myShortString) always returns 255.)

Because by definition type ShortString = string[255];  So simple and no any confusion.

You just have to think not about "magic names" but about internal implementation, data structures. What are  strings of different types in memory, if strings were record or classes - what variable would they ocntain inside?

https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Internal_Data_Formats_(Delphi)
and maybe a bit in https://www.ararat.cz/synapse/doku.php/public:howto:d2009
Modify message
« Last Edit: September 10, 2022, 04:51:11 pm by Arioch »

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #10 on: September 10, 2022, 04:56:47 pm »
Ha, yes, indeed, more confusion. ( in doc: Likewise, high(myShortString) always returns 255.)
Because by definition type ShortString = string[255];  So simple and no any confusion.

The confusion is that in doc, they dont talk about type ShortString but about the variable myShortString that can have, see your demo adapted for shortstring, other high(myshorstring) = 255.
https://forum.lazarus.freepascal.org/index.php/topic,60528.msg452970.html#msg452970

See in bottom of doc:
 https://wiki.lazarus.freepascal.org/Shortstring
« Last Edit: September 10, 2022, 05:22:02 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

avk

  • Hero Member
  • *****
  • Posts: 780
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #11 on: September 10, 2022, 05:12:40 pm »
Just curious, what does the FPC documentation say about the mentioned functions (Low(), High())?

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #12 on: September 10, 2022, 05:29:24 pm »
Just curious, what does the FPC documentation say about the mentioned functions (Low(), High())?

you are welcome - https://docs.getlazarus.org/#rtl+system+high

avk

  • Hero Member
  • *****
  • Posts: 780
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #13 on: September 10, 2022, 05:37:31 pm »
Are you sure this is a link to the official documentation?

Fred vS

  • Hero Member
  • *****
  • Posts: 3629
    • StrumPract is the musicians best friend
Re: Relationship between high(ashortstring) and length(ashortstring)
« Reply #14 on: September 10, 2022, 05:38:04 pm »
@Arioch

You seem to be a user of Delphi too.
One of the question in Spanish forum was why is there a difference in result between Delphi for this:

Code: Pascal  [Select][+][-]
  1.   program cadena;
  2. {$mode objfpc}{$H-}
  3. var
  4.     Frase: String;
  5. begin
  6.   Frase := 'Esto es una prueba';
  7.   WriteLn(low(Frase));
  8.   WriteLn(High(Frase));
  9.   WriteLn(Length(Frase));
  10.   WriteLn(Frase[500]);
  11.   Readln()
  12. end.

You may try to compile it on Delphi and compare the result with fpc.
There are also difference in warnings and crash (or not) if range is higher than high(ashortstring).
This is not a problem if we understand the logical of fpc and it is what I try.
« Last Edit: September 10, 2022, 05:47:43 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018