AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Verhindern, dass eine Funktion zwei mal den gleichen Parameter nutzt
Thema durchsuchen
Ansicht
Themen-Optionen

Verhindern, dass eine Funktion zwei mal den gleichen Parameter nutzt

Ein Thema von Alallart · begonnen am 2. Sep 2025 · letzter Beitrag vom 3. Sep 2025
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
10.111 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 2. Sep 2025, 18:21
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.
Das stimmt nicht. Das kannst du leicht testen:
Delphi-Quellcode:
function StrToBase64(Str: string; var Base64Str: string): Byte;
begin
  Base64Str := '';
  Base64Str := Str;
end;

procedure Test;
var
  a, b: string;
begin
  a := 'Test';
  StrToBase64(a, a);
  ShowMessage(a);
end;
Mit var kommt da "Test" heraus, mit out ein Leerstring.

// EDIT: Wobei ich nicht sicher bin, ob das Verhalten in der Doku genau genug definiert ist, um sich darauf auch bei zukünftigen Delphiversionen zu verlassen. Ich habe nicht nachgeschaut.

Oder ganz zu Beginn Str in eine lokale Variable kopieren,
welche aber lange genug existieren muß, was nicht automatisch sichergestellt ist.
Das bringt nichts, da Delphi den String dort schon abgeräumt hat, also vor dem begin.

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)
Du solltest es testen. Es stimmt leider nicht.

Den Vergleich hatte ich auch ausprobiert. Da darf nur nicht geprüft werden, ob Str <> '' ist wie in deinem Code, sondern nur der Pointer verglichen werden.
Sebastian Jänicke
AppCentral

Geändert von jaenicke ( 2. Sep 2025 um 18:24 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 2. Sep 2025, 19:01
ich bin mir sicher ganz viele OUT in Codes gesehen zu haben, also muß es doch funktionieren?
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Sep 2025 um 19:15 Uhr)
  Mit Zitat antworten Zitat
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, 19:02
Da darf nur nicht geprüft werden, ob Str <> '' ist wie in deinem Code, sondern nur der Pointer verglichen werden.
Wenn es ein Leerstring (nil) ist, dann ist es nicht so schlimm.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 2. Sep 2025, 19:11
ich bin mir sicher ganz viele OUT in Codes gesehen zu haben, also muß es doch funktionieren?
Es stimmt leider nicht.
such
such
such
out +[a-z0-9_]+ *: *string

20-30 Mal in unseren Codes (Firma)
und ein paar hunderte Male bei DevExpress, madExcept, JCL, pgDAC, Python4Delphi, uniGUI und Delphi (Cloud, DataSnap, EMS, DBX, FireDAC, REST, DUnit, RTL, ToolsAPI, SOAP, VCL, XML)

hmmmmmmmmmmmmmmmmmmmmmmmm
gefühlt dürfte dann ja fast garnichts mehr funktionieren?

könnte ja nochmal nachsehn/probieren




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).
Wie schon erwähnt ... bei "Konstanten" artet die Sache gleich noch mehr aus,
drum hatte ich da vorhin noch garnicht dran denken wollen,
aber stimmt, schon alleine deswegen kann es damit spaßig werden.

Tja, wie schon erwähnt, macht Delphi bei OUT mit gemadagten Typen ein bissl Mist.
(eventuell noch mehr, als gedacht)

Schöner wäre es also, wenn Delphi hier einen Compilerfehler werfen würde, anstatt irgendwie mysteriös dran rumzupfuschen, um die Speicherverwaltung nicht zu beschädigen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Sep 2025 um 19:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 2. Sep 2025, 19:52
Vielleicht haben sie in den letzten 10-15 Jahren daran mal was verändert, oder ich hatte es nicht richtig in Erinnerung oder damals falsch geguckt.

Beim OUT mit gemanagten Typen machen sie aktuell vor dem Prozedur-CALL ein Parameter:=''; (UStrClr)
Wie gesagt, sie versuchen schon ein bissl was, um die Referenzzählung der Strings nicht vollkommen zu schrotten.

Klappt nicht immer, siehe TestCode am Ende.
Und wie auch erwähnt, ist hier CONST das größere Problem.

Delphi-Quellcode:
procedure Test;
var
  a: string;
begin
  a := 'Test';

  {$REGION 'das fügt heimlich der Compiler ein'}
  a := ''; // also UStrClr(a);
  {$NDREGION}
  StrToBase64(a, a); // function StrToBase64(Str: string; OUT Base64Str: string): Byte;

  ShowMessage(a);
end;




Delphi-Quellcode:
function TestVAR(Str: string; var Res: string): Byte;
begin
  Res := '';
  Res := Str;
end;

function TestOUT(Str: string; out Res: string): Byte;
begin
  Res := '';
  Res := Str;
end;

function TestConstVAR(const Str: string; var Res: string): Byte;
begin
  Res := '';
  Res := Str;
end;

function TestConstOUT(const Str: string; out Res: string): Byte;
begin
  Res := '';
  Res := Str;
end;

// Hier wird intern das daraus "procedure TestUninitializedResult(var Result: string);",
// bei Managed Types (String, Interface, Variant, Dynamic Array, ...)
function TestUninitializedResult: string;
begin
  Result := Result + 'x';
end;

procedure TForm3.FormCreate(Sender: TObject);
var
  a, b: string;
begin
  a := 'Test'; // Konstante
  TestVAR(a, a);
  Memo1.Lines.Add(a); {Test}

  a := Copy('Test', 1, 4); // Variable
  TestVAR(a, a);
  Memo1.Lines.Add(a); {Test}

  a := 'Test';
  TestOUT(a, a);
  Memo1.Lines.Add(a); {}

  a := Copy('Test', 1, 4);
  TestOUT(a, a);
  Memo1.Lines.Add(a); {}

  a := 'Test'; // Konstante
  TestConstVAR(a, a);
  Memo1.Lines.Add(a); {Test}

  a := Copy('Test', 1, 4); // Variable
  try
    TestConstVAR(a, a);
    Memo1.Lines.Add(a); {EInvalidPointer: Ungültige Zeigeroperation}
  except
    on E: Exception do begin
      { Speichermanager zerballert : raucht im UStrClr -> _FreeMem ab }
      Memo1.Lines.Add(E.ClassName + ': ' + E.Message);
      Pointer(a) := nil; // wehe wer schimpft
    end;
  end;

  a := 'Test';
  TestConstOUT(a, a);
  Memo1.Lines.Add(a); {}

  a := Copy('Test', 1, 4);
  TestConstOUT(a, a);
  Memo1.Lines.Add(a); {}

  a := '';
  for var i := 1 to 10 do
    a := TestUninitializedResult;
  Memo1.Lines.Add(a); {xxxxxxxxxx}
end;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Sep 2025 um 19:55 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 2. Sep 2025, 19:59
Den Vergleich hatte ich auch ausprobiert. Da darf nur nicht geprüft werden, ob Str <> '' ist wie in deinem Code, sondern nur der Pointer verglichen werden.
Der Leerstring ist nicht so schlimm, finde ich, drum diesen Ausschluß,
und bei einem Leerstring kannst du HIER nicht prüfen, ob es die selbe Variable ist, weil beide NIL wären.
Und ob es nun dieselbe Variable mit NIL oder zwei unterschiedliche Variablen mit NIL, kann somit nicht geprüft werden (somit ist es mit diesem Ausschluß besser).
Hierfür müsstest du also die Adressen der Variablen prüfen, anstelle derer Inhalte.

Gehen wir einfach mal auf Nummer sicher:
Delphi-Quellcode:
function StrToBase64(const [Ref] Str: string; out Base64Str: string): Byte; // oder VAR
begin
  if @Str = @Base64Str then
    raise EProgrammerNotFound.Create('du du du 😨');


[ADD]
Ich glaub es ist eh zu umständlich, wenn wir es nachträglich innerhalb der Prozuedur prüfen.
Einfacher/Sicherer wäre es, wenn der Compiler beim Aufruf sowas prüfen und einen Fehler eine Warnung werfen könnte.
(wenn dieselbe Variable in mehrere Parameter reingegebenund wird und mindestens Einer davon ist ein OUT oder VAR)

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

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

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

  Alt 2. Sep 2025, 20:36
https://embt.atlassian.net/servicede...tal/1/RSS-4013

Code:
// (var i: Integer)  // (out i: Integer)  // (var s: string)  // (out s: string)
lea eax,[ebp-$08]    lea eax,[ebp-$08]    lea eax,[ebp-$0c]   lea eax,[ebp-$0c]
call TestVarInt      call TestOutInt      call TestVarStr     call _UStrClr
                                                              call TestOutStr


// begin             // begin             // begin            // begin
push ebp             push ebp             push ebp            push ebp
mov ebp,esp          mov ebp,esp          mov ebp,esp         mov ebp,esp
push ecx             push ecx             push ecx            push ecx
mov [ebp-$04],eax    mov [ebp-$04],eax    mov [ebp-$04],eax   mov [ebp-$04],eax
                                                              mov eax,[ebp-$04]
                                                              test eax,eax
                                                              jz NEXT
                                                              xor edx,edx
                                                              mov [eax],edx
                                                              NEXT:
// i := 1;           // i := 1;           // s := '1';        // s := '1';
mov eax,[ebp-$04]    mov eax,[ebp-$04]    mov eax,[ebp-$04]   mov eax,[ebp-$04]
mov [eax],$00000001  mov [eax],$00000001  mov edx,$008e9d90   mov edx,$008e9dc4
                                          call _UStrAsg       call _UStrAsg
// end;              // end;              // end;             // end;
pop ecx              pop ecx              pop ecx             pop ecx
pop ebp              pop ebp              pop ebp             pop ebp
ret                  ret                  ret                 ret
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 2. Sep 2025 um 21:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
10.111 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 3. Sep 2025, 05:23
Der Leerstring ist nicht so schlimm, finde ich, drum diesen Ausschluß,
Dann schlägt die Prüfung aber nie an, weil der String an der Stelle immer leer ist. Den Fall nil muss man nicht abfangen, denn der Zielstring kann nie nil sein, oder?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.522 Beiträge
 
Delphi 11 Alexandria
 
#9

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

  Alt 3. Sep 2025, 07:44
Also für mich wäre definitiv die Lösung eine echte Funktion zu machen ohne var und out. Das Funktionsergebnis wäre in diesem Fall dann ein record mit dem Byte und string. In anderen Fällen würde ich statt einem record ein Daten-Transfer-Objekt nehmen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 3. Sep 2025, 10:08
Dann schlägt die Prüfung aber nie an, weil der String an der Stelle immer leer ist.
Der Eingangs-String (Str) ist immer leer, jener, welcher auf '' geprüft wurde?
Dachte Base64Str kann/ist/darf leer?
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:45 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