View Issue Details

IDProjectCategoryView StatusLast Update
0008321FPCCompilerpublic2013-04-23 11:10
Reportertheo Assigned ToPeter Vreman  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Fixed in Version2.2.0 
Summary0008321: Incompatibility to Delphi / Kylix regarding operations on unsigned numbers
Descriptionprocedure TForm1.Button1Click(Sender: TObject);
var a,b:Byte;
begin
{.$Q+}
a:=91;
b:=84;
Edit1.text:=(intToStr(a + b - 256)); // Delphi: -81, FPC: 4294967215
end;

Delphi/Kylix always returns "-81", no matter whether Overflow checking is on.
FPC returns "4294967215" resp. with {$Q+} "EIntOverflow".
TagsNo tags attached.
Fixed in Revision6586
FPCOldBugId0
FPCTarget-
Attached Files

Relationships

has duplicate 0011297 closedJonas Maebe Expansion to 64-bit during longword calculations 
has duplicate 0012236 closedJonas Maebe converting bytes operation to 64 bit? warning message for no reason. 
related to 0024312 resolvedJonas Maebe Byte, Word, Cardinal handled in diffrent way than UInt64 

Activities

Peter Vreman

2007-02-12 21:09

administrator   ~0011404

I can't find any consistency in Delphi's handling of unsigned operations. Fixing this bug will break test tw3490. See the small program below with the outputs of FPC and Kylix.

var
 A,A2: byte;
 W : word;
 B,B2: cardinal;
  I : smallint;
begin
 B := $ffffffed;
 B2 := $fffffffd;
 Writeln(B-B2);

 W:=65535;
 A:=20;
 // FPC converts signed operations to DWord, a*w -> Dword type
 // Not sure what delphi does here....
 Writeln(a * w - 256000000);
end.

Kylix:
4294967280
-254689300

FPC unpatched:
4294967280
4040277996

FPC with patch to use int64 calculations for cardinal-cardinal:
-16
-254689300

theo

2007-02-16 12:04

reporter   ~0011494

Yes, you're probably right.
I've read:
http://www.efg2.com/Lab/Library/Delphi/MathInfo/#FloatingPointNumbers
and
http://www.efg2.com/Lab/Library/UseNet/1998/0712.txt

Still it's hard to find these problems when porting large code from Delphi.

Jonas Maebe

2007-02-16 12:48

manager   ~0011497

The problem is that we cannot make it Delphi compatible if we don' know what the rules are.

And even if we can, it's quite possible it will break again when we/you move to 64 bit. E.g.:

{$q+}
var
  b: byte;
  w: word;
  c: cardinal;
begin
  b := 100;
  w := 100;
  c := 100;
  inc(b,-1); // generates overflow error at run time in Delphi
  inc(w,-1); // generates overflow error at run time in Delphi
  inc(c,-1); // does not generate any error at all in Delphi
end.

A big problem with this is: what do we do in FPC on 64 bit platforms? Currently, give an error for inc(c,-1) there, but we do not give one for inc(qword_var,-1). This is Delphi-incompatible, but what can you do when you have nonsensical behaviour like this?

theo

2007-02-16 14:22

reporter   ~0011498

I've checked your code with K3:

All three generate an EIntOverflow, but only with Optimization off or if you actually use the var e.g. writeln(b,' ',w,' ',c);

With overflow checking off, the results however are "what you would expect"
like: 99 99 99

But I see the problem.
The best thing FPC could do is probably throwing "Incompatibilty Warnings" (if possible) or Runtime errors like it does now.

Peter Vreman

2007-02-16 15:40

administrator   ~0011499

I think the best solution for FPC is to add the fix to make cardinal-cardinal return as int64. That gives the most predictive results and is consistent with the behavior of word-word and byte-byte.

From the linked news posts it is only written that it is not seen as a delphi bug. But the rules are not written clearly either.

And as last the remark of "optimization off" makes it clearly a delphi issue, because the optimizer should change behavior of the program.

theo

2007-02-16 15:56

reporter   ~0011500

I agree about cardinal-cardinal.

But your remark about "optimization off" is not fair.
The sample code from Jonas does not produce any result or anything.
So the Kylix compiler does not generate ANY code for this in {$O+}.
You can see it in the CPU Window.
As soon as these variables are finally "used" for something, for example
writeln(b,w,c); it does generate code.

Jonas Maebe

2007-02-16 16:17

manager   ~0011501

This optimization comment is quite interesting. The current behaviour partially stems from bug 0006081. But the first inc() statement in that program indeed doesn't generate an overflow under Delphi only because it's optimized away. If you add a writeln(v), it indeed does generate an overflow under Delphi.

Florian

2007-02-16 16:43

administrator   ~0011503

Being holier than the pope one could even say the delphi optimizer is buggy. Statements with side effects shouldn't be optimized away and those inc definitively have a side effect (throwing an exception).

theo

2007-02-16 17:18

reporter   ~0011505

I really wouldn't like to argue with you, because I have almost no idea about the great work you're doing.
But doesn't this get a bit philosophic now?
I see it like this:
Jonas Code "does" nothing in the end.
So it can safely be optimized away without side effect.
It's as good as no code at all, but no code doesn't use CPU time.
If you want to know what it "would do, if it did something" ;-) for debugging purpose you can always switch to {$O-}

Jonas Maebe

2007-02-16 17:28

manager   ~0011506

The point is simply that "throwing an exception" is also doing something :) So Delphi is not only optimizing away an inc-statement, but also a raise-statement.

Florian

2007-02-16 17:39

administrator   ~0011507

Well, it's a border and I think the decision to remove the statement is correct. It's like FPC deciding to change the order how parameters are evaluted if it generates better code then.

Peter Vreman

2007-02-21 12:52

administrator   ~0011566

Cardinal-cardinal is now calculated using int64.

Issue History

Date Modified Username Field Change
2007-02-12 16:50 theo New Issue
2007-02-12 21:09 Peter Vreman Note Added: 0011404
2007-02-13 14:37 Jonas Maebe FPCOldBugId => 0
2007-02-13 14:37 Jonas Maebe FPCTarget => -
2007-02-13 14:37 Jonas Maebe Summary Incompatibility to Delphi / Kylix => Incompatibility to Delphi / Kylix regarding operations on unsigned numbers
2007-02-16 12:04 theo Note Added: 0011494
2007-02-16 12:48 Jonas Maebe Note Added: 0011497
2007-02-16 14:22 theo Note Added: 0011498
2007-02-16 15:40 Peter Vreman Note Added: 0011499
2007-02-16 15:56 theo Note Added: 0011500
2007-02-16 16:17 Jonas Maebe Note Added: 0011501
2007-02-16 16:43 Florian Note Added: 0011503
2007-02-16 17:18 theo Note Added: 0011505
2007-02-16 17:28 Jonas Maebe Note Added: 0011506
2007-02-16 17:39 Florian Note Added: 0011507
2007-02-21 12:52 Peter Vreman Fixed in Revision => 6586
2007-02-21 12:52 Peter Vreman Status new => resolved
2007-02-21 12:52 Peter Vreman Fixed in Version => 2.1.1
2007-02-21 12:52 Peter Vreman Resolution open => fixed
2007-02-21 12:52 Peter Vreman Assigned To => Peter Vreman
2007-02-21 12:52 Peter Vreman Note Added: 0011566
2007-07-29 16:55 Florian Status resolved => closed
2008-07-29 23:39 Jonas Maebe Relationship added has duplicate 0011297
2008-09-26 10:11 Jonas Maebe Relationship added has duplicate 0012236
2013-04-23 11:10 Jonas Maebe Relationship added related to 0024312