Bug oder Feature? String an Funktion übergeben und bekommen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
piula
Beiträge: 12
Registriert: Sa 2. Jan 2016, 21:25

Bug oder Feature? String an Funktion übergeben und bekommen

Beitrag von piula »

Ich habe eine Prozedur der folgenden Art:

Code: Alles auswählen

procedure test (const input: string; out result: string);
begin
  result:=input+input;
end;


Ich würde sie nun gerne mit einem String aufrufen. Es soll gleichzeitig der schon in diesem String gespeicherte Wert by value an die Prozedur übergeben und by reference das neue Ergebnis erhalten werden, also:

Code: Alles auswählen

s:='beispiel';
test(s,s);


-> Ergebnis: s = <leer>, weil schon als Parameter "input" ein leerer String an "test" übergeben wird.

Wird die Prozedur dagegen als "var result" statt "out result" deklariert, funktioniert das Konstrukt wie erwartet.

Ich würde gerne verstehen, warum es so ist, wie es ist. Oder ist das ein Compilerbug? Zumindest entspricht das beobachtete Verhalten nicht meiner Erwartung.
Zuletzt geändert von Lori am Di 1. Mär 2016, 13:22, insgesamt 1-mal geändert.
Grund: Highlighter

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Bug oder Feature? String an Funktion übergeben und bekom

Beitrag von wp_xyz »

Wegen des out-Parameters wird der Ausgangsstring zunächst mit einem Leerstring initialisiert (ein var-Parameter bleibt dagegen an dieser Stelle unverändert). Da bei deinem Aufruf Eingangs- und Ausgangsstring identisch sind, geht der Eingangsstring verloren. Verwirrend ist, dass das auch geschieht, wenn der Eingangsstring als "const" deklariert ist. Es gab dazu eine Diskussion evtl hier im Forum oder im englischen Forum, bei der Argumente vorgebracht wurden, warum das trotzdem ok ist, aber ich kann mich daran nicht mehr erinnern. Jedenfalls ist die Konstruktion kritisch. Warum versuchst du es nicht mit einer Funktion?

Code: Alles auswählen

function test(const s: String): String;
begin
  Result := s + s;
end

piula
Beiträge: 12
Registriert: Sa 2. Jan 2016, 21:25

Re: Bug oder Feature? String an Funktion übergeben und bekom

Beitrag von piula »

So in diese Richtung habe ich zwar auch schon gedacht, aber logisch erscheint es mir trotzdem nicht. Die Initialisierung des OUT-Parameters erfolgt doch erst in der Funktion, wohingegen die Übergabe des CONST-Werts noch ausserhalb geschieht. Also sollte doch zu dem Zeitpunkt, wenn der OUT-Parameter initialisiert wird, der String noch den alten Wert haben?

Eine Funktion kommt insofern nicht in Frage als es schon eine Funktion ist, die einen Erfolgswert als Rückgabeparameter liefert. Ich habe das hier nur exemplarisch verkürzt als Minimalbeispiel dargestellt.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Bug oder Feature? String an Funktion übergeben und bekom

Beitrag von wp_xyz »

Strings sind Pointer, und wenn für Eingangs- und Ausgangsstring dieselbe Variable angegeben ist, zeigen beide auf denselben Speicherbereich.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Bug oder Feature? String an Funktion übergeben und bekom

Beitrag von mse »

piula hat geschrieben:

Code: Alles auswählen

 
procedure test (const input: string; out result: string);
 


Zusätzlich zu wp_xyz's Informationen:
Mit "const" versprichst du, dass "input" nicht verändert wird. Der Compiler verlässt sich darauf und erhöht den Referenzzähler von "input" vor Verwendung nicht, was zu weiteren Problemen führen kann, falls "input" innerhalb der Prozedur auf irgendeinen Weg verändert wird. Das reicht bis hin zu SIGSEGV.

Code: Alles auswählen

 
procedure test (input: string; out result: string);
 

Ist robuster aber wegen der zusätzlichen Inkrementierung des Referenzzählers von "input" langsamer.
Die Initialisierung des OUT-Parameters erfolgt doch erst in der Funktion,

Nein, siehe
http://www.freepascal.org/docs-html/cur ... 000014.4.3
Remark: For managed types (reference counted types), using Out parameters incurs some overhead: the compiler must be sure that the value is correctly initialized (i.e. has a reference count of zero (0)). This initialization is normally done by the caller.

piula
Beiträge: 12
Registriert: Sa 2. Jan 2016, 21:25

Re: Bug oder Feature? String an Funktion übergeben und bekom

Beitrag von piula »

Vielen Dank! Dann sehe ich jetzt klarer.

Antworten