Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   ZeroBasedStrings an/aus behandeln (https://www.delphipraxis.net/209609-zerobasedstrings-aus-behandeln.html)

TurboMagic 29. Dez 2021 17:47

ZeroBasedStrings an/aus behandeln
 
Hallo,

ich habe in der DEC einen neuen Algorithmus hinzugefügt der derzeit eine RawByteString Konstante benutzt
und diese als 1-basiert betrachtet. Im Code gibt's Index Berechnungen wo derzeit ein +1 steht, man kann das
nicht mit Low(NamederKonstante) usw. abfangen.

Jetzt wollte ich im betreffenden Code die Zero Based Strings (ZBS) einfach ausschalten, da ja nutzer unter
Delphi 10.1-10.4 auf mobilen Plattformen immer ZBS an haben, nach der entsprechenden Methode wollte ich das
wieder auf den vorher aktiven Wert setzen, also falls es an war wieder anschalten.

Woanders im Code habe ich ein Konstrukt wie dieses gesehen:

{$IFOPT R+}{$DEFINE RESTORE_RANGECHECK}{$ENDIF}

Man kann also rausfinden, ob R+ gesetzt ist.
Nur das hier funktioneirt nicht, das führt zu einem Compiler Fehler:
{$IFOPT ZEROBASEDSTRINGS}{$DEFINE RESTORE_ZBS}{$ENDIF}

Warum? Gibt's dafür eine Lösung?

Grüße
TurboMagic

Uwe Raabe 29. Dez 2021 21:15

AW: ZeroBasedStrings an/aus behandeln
 
Du kannst das ganz ohne IFFEF & Co. erledigen, indem du in deinem Code mit
Delphi-Quellcode:
Low(string)
den Index des ersten Zeichens abfragst.

himitsu 30. Dez 2021 06:15

AW: ZeroBasedStrings an/aus behandeln
 
Weil besch****eise IFOPT nur für Einbuchstabige Optionen funktioniert?

Und jupp
Delphi-Quellcode:
{$IF Low(string) = 0}
. (es sollte so gehn, aber falls nicht, dann halt ein normales IF)


Notfalls einfach den String-Helper nehmen ... der arbeitet immer ab 0.

Uwe Raabe 30. Dez 2021 09:05

AW: ZeroBasedStrings an/aus behandeln
 
Zitat:

Zitat von himitsu (Beitrag 1499811)
Und jupp
Delphi-Quellcode:
{$IF Low(string) = 0}
.

Nein, so war das nicht gemeint!

Zitat:

Zitat von TurboMagic (Beitrag 1499795)
Im Code gibt's Index Berechnungen wo derzeit ein +1 steht

An diesen Stellen würde ich
Delphi-Quellcode:
+Low(string)
anstatt +1 verwenden.

himitsu 30. Dez 2021 09:48

AW: ZeroBasedStrings an/aus behandeln
 
Direkt an jeder Stelle ein +1 kann man bestimmt auch weglassen ... Den Index schon richtig laufen lassen?

Alternativen:
* String-Helper (auch wenn die Funktional oft schon bissl unoptimal arbeiten)
* PChar (der arbeitet ebenfalls schon immer 0-basiert)
* gezielt an der Stelle / in der Unit das ZEROBASEDSTRINGS so einstellen, wie man es gebrauchen kann

Delphi-Quellcode:
P := PChar(S);
if P[i] = ' ' then ...
Delphi-Quellcode:
procedure TForm5.FormCreate(Sender: TObject);
begin
  {$ZEROBASEDSTRINGS OFF}
  Caption := Caption + Low(string).ToString;

  {$ZEROBASEDSTRINGS ON}
  Caption := Caption + Low(string).ToString;
Leider funktioniert
Delphi-Quellcode:
{$ZEROBASEDSTRINGS DEFAULT}
nicht.
Und da auch $IFOPT nicht geht, ist das schon bissl unnötig unschön.

Selbst da wo DEFAULT inzwischen geht, weiß ich einfach nie, was "DEFAULT" eigentlich ist. (die Vorgabe von Emba, oder die Vorgabe aus Compiler-Parametern, bzw. Projekt-Optionen)

statt
Delphi-Quellcode:
{$ZEROBASEDSTRINGS OFF}  // oder ON
... mach was
{$ZEROBASEDSTRINGS DEFAULT}
ein
Delphi-Quellcode:
{$IF Low(string) = 0} {$DEFINE _ZEROBASEDSTRINGS_} {$ELSE} {$UNDEF _ZEROBASEDSTRINGS_} {$IFEND}
{$ZEROBASEDSTRINGS OFF}  // oder ON
... mach was
{$IFDEF _ZEROBASEDSTRINGS_} {$ZEROBASEDSTRINGS ON} {$IFEND}  // oder andersrum

TurboMagic 30. Dez 2021 10:50

AW: ZeroBasedStrings an/aus behandeln
 
Zitat:

Zitat von himitsu (Beitrag 1499811)
Weil besch****eise IFOPT nur für Einbuchstabige Optionen funktioniert?

Und jupp
Delphi-Quellcode:
{$IF Low(string) = 0}
. (es sollte so gehn, aber falls nicht, dann halt ein normales IF)


Notfalls einfach den String-Helper nehmen ... der arbeitet immer ab 0.

Es mag zwar sein, dass Uwe das nicht so gemeint hatte, aber ich hab' genau sowas gesucht und es jetzt so umgesetzt:

Delphi-Quellcode:
  {$IF Low(string) = 0}
    {$DEFINE ZBS_IS_ON}
    {$ZEROBASEDSTRINGS OFF}
  {$IFEND}

  {$IFDEF ZBS_IS_ON}
  // mein abhängiger Code
  {$ENDIF}

  // Am Ende:
  {$IFDEF ZBS_IS_ON}
    {$UNDEFINE ZBS_IS_ON}
    {$ZEROBASEDSTRINGS ON}
  {$ENDIF}
Die Daten wegen denen das gemacht wird sind ja in einem RawByteString,
weil man das "Alphabet" damit einfach komfortabler als mit einem Byte-Array
definieren kann und dadurch hängt die Basis des Index einfach am ZBS an oder aus.
Und nein: ich will nicht zur Laufzeit jedesmal die Basis für den Index Berechnen
lassen, wenn es nicht sein muss.

=> Danke für alle Beiträge, war ja auch was für mich funktionierendes dabei.

Uwe Raabe 30. Dez 2021 12:09

AW: ZeroBasedStrings an/aus behandeln
 
Zitat:

Zitat von TurboMagic (Beitrag 1499832)
Und nein: ich will nicht zur Laufzeit jedesmal die Basis für den Index Berechnen
lassen, wenn es nicht sein muss.

Das musst du auch gar nicht! Das macht der Compiler schon und ersetzt den Ausdruck
Delphi-Quellcode:
Low(string)
entweder mit 0 oder 1.

himitsu 30. Dez 2021 20:17

AW: ZeroBasedStrings an/aus behandeln
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1499842)
Das macht der Compiler schon und ersetzt den Ausdruck
Delphi-Quellcode:
Low(string)
entweder mit 0 oder 1.

Jupp, daher geht auch ein
Delphi-Quellcode:
{$IF Low(string) = 0}
, da Low(string) eine echte Konstante darstellt und bereits vom Compiler interpretiert wird.

Low(string) wird im Compiler bestimmt und eventuell sogar wegoptimiert.

MyString[Low(string)] wird immer auf 0 runtergerechnet, denn egal ob 1-Index oder 0-basierend ... intern wird es immer ein Offest 0 sein.



Wie an meinem Beispielen gezeigt, muß man in seinem Code auch garnichts entscheiden/berechnen.

Also entweder man arbeitet mit der "aktuellen" Indexberechnung, oder man arbeitet einfach immer mit einem bestimmten Offset und stellt den Code entsprechend ein.

Nur eine Ausnahme gibt es. Bei einer eigenen lokalen Compilereinstellung, muß man aufpassen, dass Indize zu externen Funktionen entsprechend umgerechnet werden, z.B. bei Verwendung von "externen" Funktionen wie Copy.

Delphi-Quellcode:
procedure TForm5.FormCreate(Sender: TObject);
begin
  var S := 'abc';
  {$ZEROBASEDSTRINGS OFF}
  Caption := Caption + ' ' + Low(string).ToString + S[1] + Copy(S, 1, 1);

  {$ZEROBASEDSTRINGS ON}
  Caption := Caption + ' ' + Low(string).ToString + S[1] + Copy(S, 1, 1);
end;
1aa 0ba

Delphi-Quellcode:
{$ZEROBASEDSTRINGS ...}
im Code gilt immer nur für die aktuelle Unit,
also ist die ganze Unit unter der eigenen Kontrolle, dann reicht es einmal zu Beginn der Unit,
und man muß sich nicht mühevoll den Zustand merken und reverten.

Genauso, wie bei Vielen der anderen Compilerschalter.

TurboMagic 31. Dez 2021 13:06

AW: ZeroBasedStrings an/aus behandeln
 
HZallo,

danke für den Hinweis, das Low schon durch den Compiler ersetzt wird!
Werde es darauf umbauen, ist natürlich weniger umständlich.

Grüße und guten Rutsch
TurboMagic


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz