The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,262 other subscribers

Archive for January 14th, 2015

Delphi: ZEROBASEDSTRINGS and maintaining cross-version Delphi libraries

Posted by jpluimers on 2015/01/14

One of the features that bites me over and over again is the ZEROBASEDSTRINGS that got introduced in Delphi XE3 and is by default ON in mobile compilers and OFF in Desktop compilers.

Back then, Mark Edington showed a small example of the effects:


procedure ZeroBasedTest;
const
S: string = '012';
begin
{$ZEROBASEDSTRINGS OFF}
Writeln(S[1]); // shows "0"
Writeln(S.Chars[1]); // shows "1"
{$ZEROBASEDSTRINGS ON}
Writeln(S[1]); // shows "1"
Writeln(S.Chars[1]); // shows "1"
end;

view raw

gistfile1.txt

hosted with ❤ by GitHub

and then explained:

The XE3 RTL source code has been refactored to be string index base agnostic. In most cases this is done by utilizing string helper functions which are always zero based.
When it is necessary to traverse a string, the Char[] property is often used to access the individual characters without concern for the current state of the compiler with respect to zero based strings.

In addition, the “Low” and “High” standard functions can now be passed a string variable to provide further flexibility as needed.
When zero based strings are enabled, Low(string) will return 0,  otherwise it will return 1. Likewise, High() returns a bounds adjusted length variation.

The problem is the non-existent forward compatibility of the other compilers (Delphi XE2 and lower).

So if you have library code that needs to work in Delphi versions, you cannot use the High and Low to make the code ZEROBASEDSTRINGS neutral.

Many Delphi developers regularly skip many Delphi versions, so these are still popular:

  • Delphi XE1 and XE2 (the last 2 compilers before Delphi really started to support mobile)
  • Delphi 2007 (the last non-Unicode Delphi compiler)
  • Delphi 7 (the last non-Galileo IDE)

The result is that library code is full of conditionan IF/IFDEF blocks like these:

Fix: this works only in XE3 or higher: “for Index := Low(input) to High(input) do // for ZEROBASEDSTRINGS”


{$ifdef GX_VER240_up}
for Index := Low(input) to High(input) do // for ZEROBASEDSTRINGS
{$else}
for Index := 1 to Length(input) do
{$endif GX_VER240_up}

view raw

gistfile1.txt

hosted with ❤ by GitHub

–jeroen

via: Mark Edington’s Delphi Blog : XE3 RTL Changes: A closer look at TStringHelper.

Posted in Ansi, Delphi, Delphi 2007, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, Encoding, Software Development, Unicode | 8 Comments »