Document and clarify assignment compatibility of ordinal types
Today I felt kinda schizophrenical when this compiled on FPC 3.2.2 without any errors:
program oh_you;
{$Mode OBJFPC}
{$RangeChecks ON}
{$OverflowChecks ON}
procedure frustration(v: Byte);
begin
writeln(v);
end;
var
f: LongInt = 12345;
d: ShortInt;
begin
//frustration(12345); // compiles if $RangeChecks=OFF
frustration(f);
frustration(Byte(f)); // outputs the same
frustration(Ord(f)); // outputs the same
d := f; // compiles as well
readln();
end.
It soon became clear that, despite Pascal being considered a strongly typed language with static type checking, this does not apply to ordinals in FreePascal, and one can safely and easily assign an integer to a variable of smaller type without an explicit cast. This will result in a value rollover, which is not unexpected but still quite surprising. But what’s even more discouraging is that the language documentation (which is really nice) doesn’t say a word about this.
Thus, I would suggest supplementing it with the following information:
- a clause about the compatibility of types of different sizes;
- an explanation of the approach used to handle integer overflow (two's complement modulo).
Also note that there are currently some statements on the wiki that are inherently wrong:
https://wiki.lazarus.freepascal.org/Typecast#conversion_versus_typecasting
For example, it says that conversion from LongWord
to Byte
must be explicit, which is false - the typecast will only prevent the run-time range check error, and only if such checks are enabled.
Also related: https://forum.lazarus.freepascal.org/index.php?topic=55610.0 - Turn off implicit type casting