[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