[fpc-pascal] Re: Fpc Access Violation if AppConfigDir doesn't exist.
Michael Müller
mueller_michael at alice-dsl.net
Wed Feb 13 08:34:24 CET 2013
Am 12.02.2013 um 13:29 schrieb Giuliano Colla:
> I've made some further experiments with my minimal test.
> Test form is just a Form with a Close button (BitBtn Kind=bkClose).
> The full code is the following:
>
> unit uinitfile;
>
> {$mode objfpc}{$H+}
>
> interface
>
> uses
> Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons,IniFiles;
>
> type
>
> { TForm1 }
>
> TForm1 = class(TForm)
> BitBtn1: TBitBtn;
> procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
> procedure FormCreate(Sender: TObject);
> private
> { private declarations }
> public
> { public declarations }
> end;
>
> var
> Form1: TForm1;
> ini: TIniFile;
> AppConfigFileName: string;
> SomeData: boolean;
> SomeOtherData: boolean;
> implementation
>
> {$R *.lfm}
>
> { TForm1 }
>
> procedure TForm1.FormCreate(Sender: TObject);
> begin
> AppConfigFileName:= '/not/existing/path/inifile.cfg';
> ini := TIniFile.Create(AppConfigFileName);
> try
> SomeData:= ini.ReadBool('Section','Val',true);
> SomeOtherData:= ini.ReadBool('Section','Val1',true);
> finally
> ini.Free;
> end;
> end;
>
> procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
> begin
> ini:= TIniFile.Create(AppConfigFileName);
> {$DEFINE Finally}
> {$IFDEF Finally}
> try
> ini.WriteBool('Section','Val',SomeData);
> ini.WriteBool('Section','Val1',SomeOtherData);
> finally
> ini.Free;
> end;
> {$ELSE}
> try
> ini.WriteBool('Section','Val',SomeData);
> ini.WriteBool('Section','Val1',SomeOtherData);
> except
> MessageDlg('Error while writing '+AppConfigFileName,mtError,[mbOK],0);
> end;
> ini.Free;
> {$ENDIF}
> end;
>
> end.
I'm not sure if somebody else mentioned this already but I have the feeling that Giuliano thinks that he has to decide to use try-finally OR try-except but there are situations where you need both. One of the criteria is if the object is local or global since for a global object it is likely that you place the .Free (or for a global object better FreeAndNil()) into a destructor or finalization section (which means that you have to stop the program in case of an error and not continue showing just a dialog) so you'll need only the try-except if you want to catch the exception. In case of a local object you'll ALWAYS have the lines
Obj := Class.Create;
try
// do some code
finally
Obj.Free;
end;
otherwise you'll end up with memory leaks.
If you want to catch the exception in this situation you'll put try-except extra around try-finally so you'll end up with
Obj := Class.Create;
try
try
// do some code
finally
Obj.Free;
end;
except
writeln('We have a problem);
halt the program or reraise the exception or raise a new one
end;
Regards
Michael
More information about the fpc-pascal
mailing list