Why 1.99 suddenly no longer equals 1.99

A strange problem suddenly occurs in all my Delphi 7 and Delphi 2009 unit tests.

I used DUnit CheckEquals to compare two Currency values, like

  CheckEquals(1.99, SomeCurrencyValue)

This worked fine in the IDE and in our build scripts, which run using the same version of DUnit for two years. Now, all of a sudden, all tests fail with strange error messages like

Expected: <1.99> - Found: <1.99>

With some newsgroup help I found that something has changed a processor flag which is responsible for floating point operations. Digging deeper in my unit tests, I found the root cause in the IBX component TIBDatabase, which seems to modify this flag.

TIBDataBase.Create(nil) changes the value of Get8087CW from $1372 to $1272, a very strange value.

procedure TForm2.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Add(Format('FPU CW = $%4.4X',[Get8087CW]));
  TIBDataBase.Create(nil);
  Memo1.Lines.Add(Format('FPU CW = $%4.4X',[Get8087CW]));
end;

Tested on two systems running Windows 2000 SP 4, InterBase 7.5.1 and 2007 libraries (gds32.dll), Delphi 7 and Delphi 2009

Why is “Self” assignable in Delphi?

This code in a GUI application compiles and runs (tested with Delphi 6 and 2009):

procedure TForm1.Button1Click(Sender: TObject);
begin
Self := TForm1.Create(Owner);
end;

Questions that come to mind:

  • why is Self writeable and not read-only?
  • in which situations could this be useful?

If you know the answer, I would be happy if you post it here or at stackoverflow.