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.