It was the tip of the iceberg. In old Pascal programs LongInt is widely used in comparing file signatures, identifiers, and also in bit fields. Four ASCII characters can easily be more than $7FFFFFFF.
In {$MODE TP} the Integer becomes SmallInt, but the functioning of LongInt remains unchanged, while in Turbo Pascal it is different.
Integer is defined as a type that changes its meaning with the mode (TP, FPC vs. ObjFPC, Delphi) while
LongInt is
always 32-bit.
Similar to how Int64 works now:
var
L: LongInt;
I: Int64;
begin
L := $FFFFFFFF;
WriteLn(L = $FFFFFFFF); { = FALSE (Turbo Pascal gives TRUE) }
I := $FFFFFFFFFFFFFFFF;
WriteLn(I = $FFFFFFFFFFFFFFFF); { = TRUE }
end.
As a result, only about half of the comparisons remain working when compiling this FPC. Need I say what will happen to the code if you cross out half the lines?
Please pay attention to the warnings that FPC generates. When I compile that code I get the following output:
Compiling .\fpctests\ttest.pp
ttest.pp(7,8) Warning: Range check error while evaluating constants (4294967295 must be between -2147483648 and 2147483647)
ttest.pp(8,13) Warning: Comparison might be always false due to range of constant and expression
Linking testoutput\ttest.exe
12 lines compiled, 0.0 sec, 28512 bytes code, 1300 bytes data
2 warning(s) issued
The first warning explicitly tells you why that comparison is wrong. FPC supports 64-bit values, this is why
$FFFFFFFF is interpreted as
signed 64-bit value. And that is not equal to
LongInt($FFFFFFFF).
You can compile with
-Sew so that all warnings are handled as errors. Please note that this really means all warnings. Using
{$warn XXX error} (where XXX is the error number you can get when compiling with
-vq) you can also selectively treat some warnings as errors. My suggestion would be to put these into an include file and to include that at the top of all of your units.
I tried to overload the comparison operator, but I got a message that this is «impossible»
operator = (D: DWord; L: LongInt) B: Boolean; Inline;
begin
B := (D = DWord(L));
end;
Only operators that don't have an internal operator can be overloaded.