Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't I get an access violation when I call methods on an uninitialized function result?

One of my coworkers show me a code written in Delphi-XE XE Version 15.0.3953.35171, which I believe it should raise an access violation. The code is bellow:

unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm3 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   function test:TstringList;
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.FormCreate(Sender: TObject);
var aStrList : TStringList;
begin
 aStrList := TStringList.Create;
 test;
 FreeAndNil(aStrList);
end;

function TForm3.test: TstringList;
var i:Integer;
begin
 for i:=0 to 1000 do
  Result.Add('aaa');//AV?
end;

end.

Inspecting aStrList and Result has the following results:

aStrList: TStringList $12FEDC : $42138A


Result: TStringList $12FEC4 : $B01B90

I do not understand why it is working. Result.Add should raise an access violation

LE: It seems that is working only on Debug Build Configuration.

like image 573
RBA Avatar asked Nov 20 '12 14:11

RBA


1 Answers

The Result variable in that function has not been initialized and could hold any value. Now, the implementation detail means that, in some combinations of compiler options, your code happens to run with Result referring to a valid object. But that's really just a coincidence of those implementation details.

If this were C++ then that function would exhibit undefined behaviour. Although that term does not have a formal meaning in Delphi, it can be helpful to use that term in a Delphi setting to mean the same thing as in the context of C++.

I would also make the point that even if Result did not refer to a valid string list object, your code would not be guaranteed to raise an access violation. It could be that Result points to a block of memory that just happens to look enough like a string list for that code to execute successfully.

If you do things properly, you can predict the behaviour of your program. If your code is flawed and induces undefined behaviour, then your program's behaviour becomes unpredictable. It may work. It may fail. Or that code may execute fine, but then lead to a failure later in the program's execution. And so on.

like image 86
David Heffernan Avatar answered Oct 20 '22 14:10

David Heffernan