Recent

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

Fred vS

  • Hero Member
  • *****
  • Posts: 3873
    • StrumPract is the musicians best friend
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #30 on: September 11, 2022, 12:06:15 am »
On Delphi doc:
http://www.delphibasics.co.uk/RTL.php?Name=High

Quote
Description
The High function returns the highest allowed value of either a type or variable of that type.
 
It only applies to character, arrays, enumerations and short strings.
 
For arrays, it returns the higest index.

So the difference is that fpc dont allow high() for short strings.
https://www.freepascal.org/docs-html/rtl/system/high.html

Quote
High

Return highest index of open array or enumerated.

OK, no problem but good to know.
« Last Edit: September 11, 2022, 01:17:58 am 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

Fred vS

  • Hero Member
  • *****
  • Posts: 3873
    • StrumPract is the musicians best friend
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #31 on: September 11, 2022, 12:53:37 am »
Sorry to monopolize but it is a hard battle.

And for the comments about missing warning if range is not OK, it is maybe because the compiler looks at size of type shortstring and not at length(thevar):

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

Warning:
Quote
cadena.pas(10,17) Warning: range check error while evaluating constants (256 must be between 0 and 255)

But with:
Code: Pascal  [Select][+][-]
  1.   WriteLn(Frase[200]));   // here no warning because 200 < length(shortstring).

No warning (it should, 200 > 18) because the check is on length(shortstring) and not length(thevariable).

Maybe.

I keep that to understand the thing for tonight so I can sleep.

 
« Last Edit: September 11, 2022, 01:50:30 am 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: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #32 on: September 11, 2022, 01:29:15 am »
i try to explain it again since you do not understand the manual that is exactly explaining everything.
shortstring is like an array[0..255], so why should a warning/hint/whatever, pop up to tell you, hey, you are INSIDE that array bounds?
it is a FIXED array.
i hope that was clear enough and you stop using wrong methods on strings or at least follow the manual that is saying all you need to know about a shortstring.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #33 on: September 11, 2022, 01:42:51 am »
another BAD example from good old pascal times would be like:
Code: Pascal  [Select][+][-]
  1. var
  2.   ss: shortstring; // we do not need to do +-H, we just define what we use
  3.   s: string; // in my case it is ansistring
  4. begin
  5.   ss[0] := char($FF); // never write to element 0, but hey, who cares, we do not need to follow the manual, we make our own rules
  6.   ss[255] := '!'; // put a char in that location
  7.   writeln(ss, ' ', length(ss)); // you guess correct, it show lots of nothing with a ! somewhere
  8.   s := ''; // strings need to be initialized, shortstrings not
  9.   setlength(s, 255); // this is the "ss[0] := char($FF);" replacement for real string types
  10.   s[255] := '!'; // again? YES!
  11.   writeln(s, ' ', length(s)); // oh, that looks different but compiler not warned me that it look different than the shortstring variant
  12.   readln;
  13. end.
« Last Edit: September 11, 2022, 01:46:03 am by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Fred vS

  • Hero Member
  • *****
  • Posts: 3873
    • StrumPract is the musicians best friend
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #34 on: September 11, 2022, 01:56:39 am »
i try to explain it again since you do not understand the manual that is exactly explaining everything.
shortstring is like an array[0..255], so why should a warning/hint/whatever, pop up to tell you, hey, you are INSIDE that array bounds?
it is a FIXED array.
i hope that was clear enough and you stop using wrong methods on strings or at least follow the manual that is saying all you need to know about a shortstring.

Cool my friend,  in this topic you did lot of jokes.
And. please, verify always before to shout.

Anyway I try to resume-understand-explain the initial Spanish topic about the difference of Delphi-Python-Java vs fpc about warnings if range is out in same condition (with shortstring).
« Last Edit: September 11, 2022, 02:18:51 am 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: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #35 on: September 11, 2022, 02:35:38 am »
Anyway I try to resume-understand-explain the initial Spanish topic about the difference of Delphi-Python-Java vs fpc about warnings if range is out in same condition (with shortstring).
i am really sorry that i can just reply in a humor way:
you buy a car, read once its manual (maybe), there you found out that it needs diesel to work.
after some years you sell it and buy a new car, no need to look into manual since you already read one (maybe), you drive to a gas station and put diesel in.
you drive away and after some meters the car just stopped working.
of course it can not be your fault since you read once (maybe) that a car needs diesel, but hey, this car not, it needs petrol.
was now the old manual wrong or you that compared new car with old car type of working?
what i try to say, keep to the manual for the product you are using  :-*
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Fred vS

  • Hero Member
  • *****
  • Posts: 3873
    • StrumPract is the musicians best friend
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #36 on: September 11, 2022, 02:39:58 am »
what i try to say, keep to the manual for the product you are using  :-*

Yes, but it is good too to have a manual that dont give confusion.  O:-)
(manual that no one reads and that's the reason for the compilation warnings.)

I stop, I have to dance.
« Last Edit: September 11, 2022, 04:12:11 am 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

paweld

  • Hero Member
  • *****
  • Posts: 1596
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #37 on: September 11, 2022, 08:06:32 am »
@Fred vS:
According to the documentation I linked to in the Spanish forum: https://www.freepascal.org/docs-html/ref/refsu9.html
---
In pascal, String is defined as: sequence of single-byte characters with an optional size specification and is always indexed from 1.

For AnsiString, this is clear because the string size is not stored at index 0, so Length(AnsiString) = High(AnsiString) and Low(AnsiString) = 1.

In the case of ShortString also Length(ShortString) = High(ShortString), but Low(ShortString) = 0, because the length of the string is stored at index 0. And since String is not an array only a "sequence of single-byte characters" then Length() does not return the length of the array (High - Low + 1) only the number of characters in the string, and index 0 is not part of the string.
Best regards / Pozdrawiam
paweld

jcmontherock

  • Sr. Member
  • ****
  • Posts: 347
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #38 on: September 11, 2022, 09:40:19 am »
Single byte character for String ? I'm using String with UTF-8 without problems...   :)
Windows 11 UTF8-64 - Lazarus 4.6-64 - FPC 3.2.2

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #39 on: September 11, 2022, 01:56:07 pm »
Single byte character for String ? I'm using String with UTF-8 without problems...   :)

@Fred vS:
According to the documentation I linked to in the Spanish forum: https://www.freepascal.org/docs-html/ref/refsu9.html
---
In pascal, String is defined as: sequence of single-byte characters with an optional size specification and is always indexed from 1.

It used to be so, before a switch to string = UNICODEString in Delphi 2009  and  then when FPC targetted at post-2009 Delphi compatibility.

Documentation grew obsolete but no one bothered.

I guess in FPC there is a switch, so FPC's string can be any of three options: String[255] aka ShortString,  long string AnsiString and long string UnicodeString
In Delphi you can choose between short and long strings ( {H+} and {H-} ) but not between flavours of long strings.

P.S. i am not sure this was ever true, though. Windows documentation makes distinction between MBCS and SBCS - single/multiple byte character sets.
Vaguely European character sets like windows-1250 (west/central Europe), windows-1252 (east Europe), windows-1251  (Russia) - were indeed mapped so one byte = one letter.
But i think hieroglyphic scripts, like most of far east languages, had more than single byte per letter even before Unicode. Never explored that mysef, so no further details. Just made i note in my memory that even AnsiString is not guaranteed to have 1 byte per letter if you transcend outside European scripts.


@Fred vS:
In the case of ShortString also Length(ShortString) = High(ShortString),

NO !!!  Remember: short strings are implemented as static-sized array of chars !!!  guess told it twice, but aside of syntactic sugar and compiler magic string[n] == array [0..n] of AnsiChar

For short string, Length(s) == Ord(s[0]) and High(s) = Max(Length(s)) (last is in pseudo-pascal)

When you make a literal constant - FPC allocates the array exactly sized for the constant. But it is not so with variables!!!

Code: Pascal  [Select][+][-]
  1. var  
  2.    ss1: shortstring;  // == string[255] by definition, but you did not spell it out
  3.    ss2: string[40];
  4. const
  5.    ssc = '1234567890ABCDEFGHIJKLMNO';
  6.  
  7. procedure Dump;
  8. begin
  9.    WriteLn(  'const': 20, High(ssc): 8, Length(ssc): 8, ssc:40);
  10.    WriteLn(  'var "unlim"': 20, High(ss1): 8, Length(ss1): 8, ss1:40);
  11.    WriteLn(  'var lim': 20, High(ss2): 8, Length(ss2): 8, ss2:40);
  12.    WriteLn;
  13. end;
  14.  
  15. begin
  16.    ss1 := ssc;
  17.    ss2 := ss1;  // compiler should throw warning here, think WHY it is throwing it, WHAT is compiler afraid of?
  18.  
  19.    Dump;
  20.  
  21.    ssc[0] := #4;  // try it - won't work, it is const array
  22.    ss1[0] := #4;  // this was way to go, before SetLength existed. Actually there was nothing
  23.    ss2[0] := #4;  // at all for SetLength to do in 16-bit Delphi/Pascal, so there was no such function
  24.  
  25.    Dump;
  26.  
  27.    ss1[0] := #35;
  28.    ss2[0] := #35;
  29.  
  30.    Dump;
  31.  
  32.    ReadLn;
  33. end.
  34.  
« Last Edit: September 11, 2022, 02:01:23 pm by Arioch »

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #40 on: September 11, 2022, 01:59:56 pm »
On Delphi doc:
http://www.delphibasics.co.uk/RTL.php?Name=High

Oh, and don't claim that was "Delphi doc". It is someone's personal moderated FAQ collection.

I guess that was exactly the place (or some other UK site) which championed "correct way to compare numbers", and guess what it was? It was

Code: Pascal  [Select][+][-]
  1.    var f,g : double;
  2.    begin
  3.        if FloatToStr(f) = FloatToStr(g) then ...
  4.    end;
  5.  

So please, whatever you read on whatever forum is NOT documentation but only a hint, and it is still on you to understand it, to extend and complete it, and to veriify it.

In the end....

« Last Edit: September 11, 2022, 02:03:26 pm by Arioch »

PascalDragon

  • Hero Member
  • *****
  • Posts: 6381
  • Compiler Developer
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #41 on: September 11, 2022, 05:18:03 pm »
No warning (it should, 200 > 18) because the check is on length(shortstring) and not length(thevariable).

Correct, there is no warning and there should not be, because the compiler does not know that you set the length of the string to 18. This would require data flow analysis which might be done in higher optimization levels (to optimize assignment involving constants), but definitely not in the base of the language. And the memory allocated for a ShortString variable is always 256 Byte, so any access there is valid (though the length of the string will only change upon a change of StringVar[0] or an assignment of another string). The memory allocated for a String[100] variable is always 101 Byte.

And Delphi behaves the same as FPC for ShortString with High and Low. That strings aren't mentioned in the documentation for High and Low can be reported on the bug tracker.

Fred vS

  • Hero Member
  • *****
  • Posts: 3873
    • StrumPract is the musicians best friend
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #42 on: September 11, 2022, 05:37:35 pm »
No warning (it should, 200 > 18) because the check is on length(shortstring) and not length(thevariable).

Correct, there is no warning and there should not be, because the compiler does not know that you set the length of the string to 18. This would require data flow analysis which might be done in higher optimization levels (to optimize assignment involving constants), but definitely not in the base of the language. And the memory allocated for a ShortString variable is always 256 Byte, so any access there is valid (though the length of the string will only change upon a change of StringVar[0] or an assignment of another string). The memory allocated for a String[100] variable is always 101 Byte.

And Delphi behaves the same as FPC for ShortString with High and Low. That strings aren't mentioned in the documentation for High and Low can be reported on the bug tracker.

Ho so happy that you finally appear!  ;D

OK, perfect, like always, clear, short and efficient.
And also like always, and I know it, verify for what I fight, I dont have Delphi to test what warning or no, if is true of false what people affirm, so I should not fight.

Hum, last little stupid question if you are still in the neighbourhood...

Quote
Correct, there is no warning and there should not be, because the compiler does not know that you set the length of the string to 18.

And with this he does not know?  :-\

Code: Pascal  [Select][+][-]
  1. var
  2.     Frase: String = 'Esto es una prueba';

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: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #43 on: September 11, 2022, 08:39:11 pm »
Code: Pascal  [Select][+][-]
  1.   s := ''; // strings need to be initialized, shortstrings not
  2.  

Do it? Managed types are auto-initialized to nil (and auto-destroyed when the function/program exits)

Code: Pascal  [Select][+][-]
  1.   writeln(ss, ' ', length(ss)); // you guess correct, it show lots of nothing with a ! somewhere
  2. .

In the ideal world. In real world there is a significant chance to have #0 somewhere befor last character and then some OS function cancelling output on the first #0 met.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6381
  • Compiler Developer
Re: [Solved] Relationship between high(ashortstring) and length(ashortstring)
« Reply #44 on: September 12, 2022, 01:49:28 pm »
No warning (it should, 200 > 18) because the check is on length(shortstring) and not length(thevariable).

Correct, there is no warning and there should not be, because the compiler does not know that you set the length of the string to 18. This would require data flow analysis which might be done in higher optimization levels (to optimize assignment involving constants), but definitely not in the base of the language. And the memory allocated for a ShortString variable is always 256 Byte, so any access there is valid (though the length of the string will only change upon a change of StringVar[0] or an assignment of another string). The memory allocated for a String[100] variable is always 101 Byte.

And Delphi behaves the same as FPC for ShortString with High and Low. That strings aren't mentioned in the documentation for High and Low can be reported on the bug tracker.

Ho so happy that you finally appear!  ;D

I was on a LARP, I simply had no computer access there.
Quote
Correct, there is no warning and there should not be, because the compiler does not know that you set the length of the string to 18.

And with this he does not know?  :-\

Code: Pascal  [Select][+][-]
  1. var
  2.     Frase: String = 'Esto es una prueba';

The compiler knows that the constant 'Esto es una prueba' has a specific length, however you are assigning it to a variable (typed constant would be the same here by the way) and with that the compiler looses any knowledge about the length, because it's after all no longer a constant, but a variable and it might be changed from somewhere else. This is where my point regarding data flow analysis comes in: if the compiler can prove that Frase still contains the string assigned in the initialization then (and only then) it can do things based upon this knowledge. But, again, Data Flow Analysis is expensive. Thus it's only done in higher optimization cases and even then not everything might be covered yet (e.g. currently string constants might not be handled by the DFA and ConstProp optimizations, but they could).

Code: Pascal  [Select][+][-]
  1.   s := ''; // strings need to be initialized, shortstrings not
  2.  

Do it? Managed types are auto-initialized to nil (and auto-destroyed when the function/program exits)

If your String is a result variable then you should initialize it nevertheless, cause due to how string results are passed to and from functions you might get another string in there.

Code: Pascal  [Select][+][-]
  1.   writeln(ss, ' ', length(ss)); // you guess correct, it show lots of nothing with a ! somewhere
  2. .

In the ideal world. In real world there is a significant chance to have #0 somewhere befor last character and then some OS function cancelling output on the first #0 met.

The OS functions won't cancel that, because the same functions are also used for writing binary data which can contain #0 as well. What might happen however is that your terminal might not display data beyond the first #0.

 

TinyPortal © 2005-2018