Could somebody help me explain why the TStrings is returned as "Inaccessible value" when an exception is raised in the underlyning function?
function GetStrings():TStrings;
begin
result := TStringList.Create;
try
raise exception.Create('Error Message');
except
FreeAndNil(result);
raise
end;
end;
procedure TFormMain.Button1Click(Sender: TObject);
var
S : TStrings;
begin
try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;
end;
The function GetStrings
also returns "Inaccessible value" if I don't call FreeAndNil(result);
prior to reraising the exception. However, then I have a memory leak on my hands aswell :-O
try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;
Here is the sequence of execution:
S
is a local variable, its value is indeterminate until is has been initialized. That is the state as this code begins execution.GetStrings
function is called.GetStrings
. Which means that GetStrings
does not return execution to the caller and so has the consequence that S
is never assigned.finally
block does not execute because its try was never reached.except
block executes, and S
has indeterminate value, which is what you have observed.In fact, the compiler should warn (W1036) that S
might not have been initialized when you refer to it in the except
block. But it doesn't seem to be able to do that, which is rather pathetic.
If you wish to be able to refer to S
in your except
block, you will need to nest it inside the try/finally
.
S := GetStrings;
try
try
//Do awesome stuff
except
//Do stuff with S
Assert(S <> nil);
end;
finally
FreeAndNil(S)
end;
Another way of thinking about this is that S
is only meaningful in between the code that assigns to S
, and the code that destroys the object. The consequence being that the try/except
must be nested inside the try/finally
, if the except
block is going to be able to refer to the object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With