Ian Branch 127 Posted November 13, 2020 Hi Guys, Is there anything actually wrong with creating an object in a TRY block or is it just not good practice? Are there Pros & Cons? I ask because FixInsight flags it with a Warning. Regards & TIA, Ian Share this post Link to post
Anders Melander 1783 Posted November 13, 2020 21 minutes ago, Ian Branch said: Is there anything actually wrong with creating an object in a TRY block or is it just not good practice? It depends. Do either this: Foo := TFooBar.Create; try ... finally Foo.Free; end; or this: Foo := nil; try Foo := TFooBar.Create; ... finally Foo.Free; end; 1 Share this post Link to post
Ian Branch 127 Posted November 13, 2020 Hi Anders, I was using the second but without the Foo := nil; Adding the equivalent of Foo := nil; to my code eliminates the FI Warning. I think I will use the first method to avoid any complications. Regards & Tks again. Ian Share this post Link to post
David Heffernan 2345 Posted November 13, 2020 (edited) try Foo := TFooBar.Create; ... finally Foo.Free; end; Consider the above. Suppose that TFooBar.Create raises an exception. In that case the finally block is executed, and `Foo.Free` is called on an uninitialised variable (Foo). That leads to undefined behaviour. So the correct pattern is Foo := TFooBar.Create; try ... finally Foo.Free; end; Here, if TFooBar.Create raises an exception, the try is never reached, and so the finally block never executes. Now another pattern was also mentioned Foo := nil; try Foo := TFooBar.Create; ... finally Foo.Free; end; This is also valid, because Foo is initialised before the try executes. And so in case of constructor exception we would call Free on a nil reference which is fine. However, this pattern is pointless and should be avoided in the scenario here where there is just a single object. It is useful sometimes if there are multiple objects and you want to avoid deep nesting. A better example of using this pattern is if the object is created conditionally: Foo := nil; try if someTest then begin Foo := TFooBar.Create; ... end; ... finally Foo.Free; end; Edited November 13, 2020 by David Heffernan 4 Share this post Link to post