Recent

Author Topic: Base of string and dynamic array types  (Read 5280 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 7423
Base of string and dynamic array types
« on: June 29, 2024, 09:44:11 pm »
As an experiment, I've just written this:

Code: Pascal  [Select][+][-]
  1. type
  2.   String31= string[31];
  3.  
  4. procedure experiment;
  5.  
  6. var
  7.   i: integer;
  8.  
  9. begin
  10.   i := Low(String31);
  11.   i := High(String31)
  12. end;
  13.  

The result of the Low() operation was zero, while the first valid character is 1.

What operation can be applied to a string type to return 1, and a dynamic array type to return 0?

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

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #1 on: June 29, 2024, 09:47:43 pm »
Which mode?
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

MarkMLl

  • Hero Member
  • *****
  • Posts: 7423
Re: Base of string and dynamic array types
« Reply #2 on: June 29, 2024, 09:58:32 pm »
Which mode?

Code: Pascal  [Select][+][-]
  1. {$mode ObjFPC}{$H+}
  2.  

Inserted by the Lazarus IDE.

I think that it's distinguishing between the two "type families" that's interesting here. Xref to https://forum.lazarus.freepascal.org/index.php/topic,67670.msg521921.html#msg521921 where "that leaves the very uncomfortable situation that moving between different families of types (i.e. Pascal's strings vs dynamic arrays) or between text representation in related languages (Pascal vs Modula-2) means changing from 1-based to 0-based indexing."

I presume that a type helper could do something equivalent to the Low() function...

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

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #3 on: June 30, 2024, 09:08:26 am »
{$zerobasedstrings on} this is added for delphi compatibility....
In Delphi type helpers for string types are always zero based indexed.
I don't know if our string type helpers also  do that in the delphi modes.
Exists since 3.0.
one based indexing is by convention, there is no intrinsic to return that.
« Last Edit: June 30, 2024, 09:43:39 am by Thaddy »
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

MarkMLl

  • Hero Member
  • *****
  • Posts: 7423
Re: Base of string and dynamic array types
« Reply #4 on: June 30, 2024, 06:34:34 pm »
{$zerobasedstrings on} this is added for delphi compatibility....
In Delphi type helpers for string types are always zero based indexed.
I don't know if our string type helpers also  do that in the delphi modes.
Exists since 3.0.
one based indexing is by convention, there is no intrinsic to return that.

I don't /want/ zero based strings. I want to find out the index of the first usable character, so that similar-patterned code can be applied to both a string and a dynamic array.

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

jcmontherock

  • Sr. Member
  • ****
  • Posts: 261
Re: Base of string and dynamic array types
« Reply #5 on: June 30, 2024, 06:48:31 pm »
I believed that function Low() and High() were only designed for dynamic array (?). String is not a dynamic  array.
Windows 11 UTF8-64 - Lazarus 3.4-64 - FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #6 on: June 30, 2024, 07:10:53 pm »
strings belong to the array family, only by convention they start at 1.
by that convention, all string types have their first usuable character as char=string[1]
That is, only when converting some delphi code above XE and below 10.4 you would need the conditional I referred to. Delphi reversed it later back to index 1.
On shortstrings, like Mark uses, Index 0 holds the string length as byte. with other string types that information is a negative offset  too, but 0 is valid.
Basically  delphi restored its behavior with strings back to normal 1 indexing in 10.4.
In FreePascal it was always optional. You may assume the first valid char in a string is at string[1] in both dialects.

With hindsight it is a good thing that {$zerobasedstrings on} was never properly documented. Units that use it should be marked either platform or deprecated.
That leaves us with just Low() on strings being counter-intuitive.
« Last Edit: June 30, 2024, 09:53:59 pm by Thaddy »
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5644
  • Compiler Developer
Re: Base of string and dynamic array types
« Reply #7 on: June 30, 2024, 11:02:51 pm »
As an experiment, I've just written this:

Code: Pascal  [Select][+][-]
  1. type
  2.   String31= string[31];
  3.  
  4. procedure experiment;
  5.  
  6. var
  7.   i: integer;
  8.  
  9. begin
  10.   i := Low(String31);
  11.   i := High(String31)
  12. end;
  13.  

The result of the Low() operation was zero, while the first valid character is 1.

What operation can be applied to a string type to return 1, and a dynamic array type to return 0?

String[N] is always a ShortString, thus the element at index 0 is the length of the string and valid for usage (both read and write). For non-ShortString types Low() will return 1 (unless $ZeroBasedStrings is enabled).

jcmontherock

  • Sr. Member
  • ****
  • Posts: 261
Re: Base of string and dynamic array types
« Reply #8 on: July 01, 2024, 11:23:58 am »
which differences with AnsiString (not short string I believe) ?
Windows 11 UTF8-64 - Lazarus 3.4-64 - FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #9 on: July 01, 2024, 12:18:56 pm »
ansi, unicode wide strings all start at 1. The Pchar types not, except cast:
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$APPTYPE CONSOLE}
  3. var
  4.   a:AnsiString = 'testa';
  5.   b:UnicodeString = 'testu';
  6.   c:WideString = 'testw';
  7.   d:UTF8String = 'test8';
  8.   e:PAnsiChar = 'testPA';
  9.   f:PWideChar  = 'testPW';
  10. begin
  11.   writeln(low(a));
  12.   writeln(low(b));
  13.   writeln(low(c));
  14.   writeln(low(d));
  15.   writeln(low(AnsiString(e))); // needs cast.
  16.   writeln(low(WideString(f)));
  17. end.
« Last Edit: July 02, 2024, 05:57:38 pm by Thaddy »
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

jcmontherock

  • Sr. Member
  • ****
  • Posts: 261
Re: Base of string and dynamic array types
« Reply #10 on: July 02, 2024, 11:46:35 am »
What is "r" in your example ?
« Last Edit: July 02, 2024, 11:51:16 am by jcmontherock »
Windows 11 UTF8-64 - Lazarus 3.4-64 - FPC 3.2.2

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #11 on: July 02, 2024, 05:57:11 pm »
Debug stuff that can be removed. I removed it.
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

MarkMLl

  • Hero Member
  • *****
  • Posts: 7423
Re: Base of string and dynamic array types
« Reply #12 on: July 03, 2024, 11:15:25 am »
I believed that function Low() and High() were only designed for dynamic array (?). String is not a dynamic  array.

In that case why do low and high accept strings as parameters?

AIUI it would be feasible for a generic procedure to accept either a string (of various types) or a dynamic array as a parameter. At that point being able to refer to the first storage element (i.e. as distinct from String[0] which is more along the lines of metadata) is essential.

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

Thaddy

  • Hero Member
  • *****
  • Posts: 15488
  • Censorship about opinions does not belong here.
Re: Base of string and dynamic array types
« Reply #13 on: July 03, 2024, 11:28:38 am »
Because he did not understand that the string types are a higher abstraction from a dynamic array? I tried to answer that. Sven explained why the exception is shortstring, I explained the exception for the pointer types, which, by casting, causes copy on write. I forgot to mention that.
Any string type, with the exception of shortstrings declared with a given length, is essentially a dynamic array, differing in how it is managed.
- shorstrings declare length at byte zero
- PChar types terminate with #0 (and use the inefficient strlen() to determine length)
- all other strings named string store size and refcount at negative offset from [1]
- except the quirky use of {$zerobasedstrings on} which is deprecated by its introducer: Delphi and only existed for a few releases.
« Last Edit: July 03, 2024, 11:37:20 am by Thaddy »
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

MarkMLl

  • Hero Member
  • *****
  • Posts: 7423
Re: Base of string and dynamic array types
« Reply #14 on: July 03, 2024, 11:32:54 am »
I'm tempted to speculate on whether String[0] (or for that matter Array[-1]) could usefully be a different type from the remainder of the structure and used to refer to the metadata (i.e. length, plus in the case of strings codepage etc.).

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

 

TinyPortal © 2005-2018