Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2009-06

FPC Delphi compatibility question...

15 messages · 9 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bruce Tulloch

I found what appears to a subtle difference between the Delphi & Kylix3 handling of dynamic array assignment and FPC in Delphi mode. If an assignment is made along the lines:

type
    TArray : array of Integer;
var
    A, B : TArray;
    I : Integer;
type
    function F ( C : TArray ) : TArray;
    begin
       { does nothing }
    end
begin
    SetLength(B,4);
    for I := 0 to 3 do
       B[I] := I;
    A := Copy(B);
    A := F(B); { what is the correct answer here? }
end;

a question arises as to the value of A. Should it be nil or should it be a copy of B?

Delphi and Kylix assume that because the function F does not assign a value to Result (ie, does not assign a return value) that the Lvalue assigned from F remains unchanged.

FPC assigns nil to A which IMHO is correct, but not when run in "bug for bug" Delphi compatibility mode.

Obviously F not assigning Result is a programming error, but unfortunately it can be a common one in legacy code.

What do others think about this compatibility difference?

Should it be fixed or should (possibly large) legacy codebases be debugged?

Cheers, Bruce.

Reply by email

Vincent Snijders
to Bruce Tulloch
Bruce Tulloch wrote
FPC assigns nil to A which IMHO is correct, but not when run in "bug for bug" Delphi compatibility mode.

I don't think there exists a "bug for bug" Delphi compatibility mode.

Vincent

Reply by email

Jonas Maebe
to Bruce Tulloch: I found what appears to a subtle difference between the Delphi & Kylix3 handling of…
Bruce Tulloch wrote 18 lines
type function F ( C : TArray ) : TArray; begin { does nothing } end begin SetLength(B,4); for I := 0 to 3 do B[I] := I; A := Copy(B); A := F(B); { what is the correct answer here? } end; a question arises as to the value of A. Should it be nil or should it be a copy of B?

Both are correct from a compiler implementation point-of-view, because the result of your function call is undefined.

Obviously F not assigning Result is a programming error, but unfortunately it can be a common one in legacy code.

As Vincent indicated, we do not aim for implementing the same undefined behaviour as Delphi (we already have our hands full with implementing the defined behaviour ;)

Jonas

Reply by email

Bruce Tulloch
to Vincent Snijders: I don't think there exists a "bug for bug" Delphi compatibility mode. Vincent
Vincent Snijders wrote 6 lines
Bruce Tulloch schreef: > FPC assigns nil to A which IMHO is correct, but not when run in "bug for > bug" Delphi compatibility mode. > I don't think there exists a "bug for bug" Delphi compatibility mode.

I'm sure there isn't which is why I quoted the term "bug for bug".

My question is really along the lines of "is this a simple functional difference to change in FPC?" and if it is, "should we change FPC behaviour to match Delphi in this respect when FPC is compiling source in Delphi mode?".

Bruce.

Reply by email

Maxim Egorov
to Bruce Tulloch: I found what appears to a subtle difference between the Delphi & Kylix3 handling of…

Bruce Tulloch пишет:

Show quoted text 7 lines
Delphi and Kylix assume that because the function F does not assign a value to Result (ie, does not assign a return value) that the Lvalue assigned from F remains unchanged. FPC assigns nil to A which IMHO is correct, but not when run in "bug for bug" Delphi compatibility mode.

I guess that the behavior of FPC is correct and expectable. I just try your example in Delphi 7, 2007, 2009 and was amazed. They indeed don't assign anything to the array A. This is a Delphi compiler bug. FPC must not copy delphi compiler mistakes. :)

Regards,
Maxim

Reply by email

Graeme Geldenhuys
to Maxim Egorov
Maxim Egorov wrote
your example in Delphi 7, 2007, 2009 and was amazed. They indeed don't assign anything to the array A. This is a Delphi compiler bug. FPC must

Maybe somebody should be nice and report this in the CodeGear QC, so Delphi can be fixed in the future (probably 8-10 years from now).

[Sorry, I didn't mean to be nasty - CodeGear is trying there best to rectify the huge backlog of bugs]

Regards,
- Graeme -

_______________________________________________________ fpGUI - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/

Reply by email

Micha Nelissen
to Maxim Egorov: Bruce Tulloch пишет: I guess that the behavior of FPC is correct and expectable. I…
Maxim Egorov wrote
I guess that the behavior of FPC is correct and expectable. I just try your example in Delphi 7, 2007, 2009 and was amazed. They indeed don't assign anything to the array A. This is a Delphi compiler bug. FPC must not copy delphi compiler mistakes. :)

Since the return value is undefined, anything is possible:
* calculate crc32 over executable
* random value from stack
* do nothing at all

Micha

Reply by email

Maxim Egorov
to Micha Nelissen: Since the return value is undefined, anything is possible: * calculate crc32 over…

Micha Nelissen пишет:

Show quoted text 5 lines
Since the return value is undefined, anything is possible: * calculate crc32 over executable * random value from stack * do nothing at all

It's not true in the case of functions that return dynamic arrays, strings or interfaces. Because of these types require special finalization and they must be initialized to nil by default. So the expected behavior is:
1) the result value must be nil
2) the compiler must show warning "function needs return value"

P.S. Delphi doesnt return nil and doenst show warning.

Reply by email

Jonas Maebe
to Maxim Egorov
Maxim Egorov wrote 9 lines
Micha Nelissen пишет: > Since the return value is undefined, anything is possible: > * calculate crc32 over executable > * random value from stack > * do nothing at all > It's not true in the case of functions that return dynamic arrays, strings or interfaces. Because of these types require special finalization and they must be initialized to nil by default.

That is an implementation detail, and not something you can rely on as far as semantics are concerned.

Jonas

Reply by email

Florian Klaempfl
to Jonas Maebe
Show quoted text 15 lines
On 19 Jun 2009, at 12:01, Maxim Egorov wrote: > Micha Nelissen пишет: >> Since the return value is undefined, anything is possible: >> * calculate crc32 over executable >> * random value from stack >> * do nothing at all >> > It's not true in the case of functions that return dynamic arrays, > strings or interfaces. Because of these types require special > finalization and they must be initialized to nil by default. That is an implementation detail, and not something you can rely on as far as semantics are concerned.

Variables of those types are initialized to nil at scope entry. I'd consider result as variable.

Reply by email

Jonas Maebe
to Florian Klaempfl
Florian Klaempfl wrote 14 lines
Jonas Maebe schrieb: > > On 19 Jun 2009, at 12:01, Maxim Egorov wrote: > >> It's not true in the case of functions that return dynamic arrays, >> strings or interfaces. Because of these types require special >> finalization and they must be initialized to nil by default. > > That is an implementation detail, and not something you can rely on > as > far as semantics are concerned. Variables of those types are initialized to nil at scope entry. I'd consider result as variable.

Yes, but as far as I am concerned that is an implementation detail (it's done because otherwise you get crashes when assigning something to such variables due to the way the garbage collection is implemented). This means that if you have an undefined value, the compiler should be free to replace this undefined value with whatever it wants (since the result is semantically undefined anyway, why not make it as efficient as possible?).

Jonas

Reply by email

Maxim Egorov
to Jonas Maebe

Jonas Maebe пишет:

Show quoted text 25 lines
On 19 Jun 2009, at 13:21, Florian Klaempfl wrote: > Jonas Maebe schrieb: >> >> On 19 Jun 2009, at 12:01, Maxim Egorov wrote: >> >>> It's not true in the case of functions that return dynamic arrays, >>> strings or interfaces. Because of these types require special >>> finalization and they must be initialized to nil by default. >> >> That is an implementation detail, and not something you can rely on as >> far as semantics are concerned. > > Variables of those types are initialized to nil at scope entry. I'd > consider result as variable. Yes, but as far as I am concerned that is an implementation detail (it's done because otherwise you get crashes when assigning something to such variables due to the way the garbage collection is implemented). This means that if you have an undefined value, the compiler should be free to replace this undefined value with whatever it wants (since the result is semantically undefined anyway, why not make it as efficient as possible?).

Maybe you are right. But i guess that the current FPC implementation allows to find such errors more quickly. So maybe it would be useful to save it for debug purposes.

Reply by email