Hello,
I was reading the thread
https://forum.lazarus.freepascal.org/index.php/topic,50896.msg372511.html#msg372511 which is now locked and, wanted to provide an explanation that hopefully makes it clear why the compiler behaves the way it does, that is requiring an _apparently_ superfluous typecast.
consider this:
const
ACONTANT = $FF;
var
Variable : integer = 100;
begin
Variable := Variable + ACONSTANT;
end.
Should the result of that expression be 355 (100 + 255) or 99 (100 - 1) ?... without the compiler knowing the type associated with the constant, the expression is ambiguous and there is no way for the compiler to resolve the ambiguity. The problem is, there is no way to decide if $FF should be interpreted as signed or unsigned, there is simply not enough information in $FF to unambiguously make the decision.
Now, what happens if instead of a constant, the declaration was a typed variable ? ... like this:
var
AByte : byte = $FF;
Variable : integer = 100;
begin
Variable := Variable + AByte;
end.
In this case, there is
_apparently_ no problem. AByte should be 255 but, there is still a problem. The problem is that in the constant $FF there is simply no type information, it could be either as -1 (which would be a range error in this case) or 255.
The different way of seeing what $FF is, occurs in the
scanning portion of the compiler, _not_ the parser. When the scanner finds $FF, it has to _somehow_ return that value to the parser. In the case of FPC, it picks an integer type (IntXX/int32/int64) and tells the parser that there is a "symbol_numeral, value = -1". IOW, the parser gets whatever type the
scanning portion of the compiler decided to use to represent that bit sequence which, as the example above shows, isn't necessarily the desired interpretation (in the example above, -1 is a range error since a "byte" type cannot accommodate a negative value.)
It's important to realize that the scanner doesn't parse. The scanner has _no_ clue whatsoever that the type is "byte". All it knows is that there is a hex constant in the source and that it has to produce and send an "equivalent" value to the parser. FPC's implementation picks "integer", produces the equivalent value based on that interpretation and hands that over to the parser.
Hopefully, that makes it understandable why the additional, apparently superfluous, cast is necessary.
HTH.