Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#3

AW: Verhindern, dass eine Funktion zwei mal den gleichen Parameter nutzt

  Alt 2. Sep 2025, 17:30
Alleine ein VAR anstelle des OUT bringt nicht wirklich eine Veränderung/Lösung.


Jupp, eigentlich würde OUT hier die automatische Speicherverwaltung eines Strings zerschießen,
aber Delphi macht hier heimlich ein VAR aus dem OUT.
Alleine das Erklärt bereits, warum es nichts ändern wird.


Tipp: Wenn du ganz sicher gehn willst,
dann das Ergebnis erst in eine lokale Variable
und ganz zum Schluß ein Result := DeineVariable; .

Oder ganz zu Beginn Str in eine lokale Variable kopieren,
welche aber lange genug existieren muß, was nicht automatisch sichergestellt ist.




Delphi-Quellcode:
function StrToBase64(const Str: string; out Base64Str: string): Byte;
begin
  //if IntPtr(Str) = IntPtr(Base64Str) then
  if (IntPtr(Str) = IntPtr(Base64Str)) and (Str <> '') then
    raise EProgrammerNotFound.Create('du du du 😨');
Man beachte das CONST.

ABER, da du kein CONST angegeben hast, gibt es hier keine Probleme, denn Str ist innerhalb der Funktion quasi eine Kopie.
OK, nicht wirklich, aber die Refferenzzählung ist erhöht, womit beim ersten Schreibzugriff auf Base64Str die Referenzzählung auf 1 gebracht wird, also ab dann sind es zwei unterschiedliche Strings.

Meine Prüfung würde aber "gleich zu Beginn" dennoch einen Fehler werfen, auch wenn er eigenlich unnötig wäre.



PS: MIT CONST gibt es hier erst einen richtigen Fehler, wenn der String vor Funktionsaufruf einen RefCount von 1 hat.

Delphi-Quellcode:
S := 1.ToString;
StrToBase64(S, S);

function StrToBase64(const Str: string; out Base64Str: string): Byte;
begin
  Base64Str := '';
  ShowMessage(Str); // hier kommt '' raus
Delphi-Quellcode:
S := 1.ToString;
StrToBase64(S, S);

function StrToBase64(Str: string; out Base64Str: string): Byte;
begin
  Base64Str := '';
  ShowMessage(Str); // hier kommt '1' raus
Delphi-Quellcode:
S := 1.ToString;
S2 := S;
StrToBase64(S, S);

function StrToBase64({const} Str: string; out Base64Str: string): Byte;
begin
  Base64Str := '';
  ShowMessage(Str); // hier kommt '1' raus, egal ob mit oder ohne const
(hab das jetzt nicht getestet, aber rein logisch müsste es passen)

PS: S := '1'; ist etwas anderes, als ein S := 1.ToString; ,
denn '1' ist eine Konstante (RefCount = -1) und das Andere ergibt wirklich eine Variable (RefCount = +1).


PSS: Genau das ist auch der Grund, bzw. Einer davon, warum in vielen meiner Codes/Komponenten absichtlich oft kein CONST verwendet wird.
(nicht nur, aus Faulheit oder weil der Code dann kürzer und übersichtlicher ist)

Besonders schlimm wird es mit Interfaces bei RefCount=1,
z.B. wenn man ein "Objekt" erstellt und es direkt an einen Interface-Parameter übergibt.
Machwas(TIrgendwas.Create);
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Sep 2025 um 17:56 Uhr)
  Mit Zitat antworten Zitat