This ocurrs because the size/type of plain integer literals can't be determined without making some guesses;
here's what FPC does:
That means constants in the range -128..127 are mapped to shortint, constants in range 128..255 are mapped to byte, etc. Constants in the range 2147483647..high(cardinal) are parsed as cardinals, and all decimal constants which do not fit either of the above ranges are parsed as 64-bit integer constants.
So in your case, the compiler assumes that
24 is a
ShortInt in both calls. But
F1(Byte; ShortInt) doesn't exist, and because there are exactly two possibilities that are
equally valid (
Byte & Byte or
ShortInt & ShortInt), the compiler can't make a guess. Usually it settles with the candidate where the most parameters match, but a 50:50 split is undecidable. Take a look at this little experiment and note how (again) it's the equally-split case that fails:
function F(A, B, C, D: Byte): SizeInt; inline;
begin
Result := 2;
end;
function F(A, B, C, D: ShortInt): SizeInt; inline;
begin
Result := 1;
end;
procedure Test();
begin // xor eax, eax
PSizeInt(Nil)^ := F(100, 100, 100, 100); // mov [eax], 1 - ShortInt
PSizeInt(Nil)^ := F(200, 100, 100, 100); // mov [eax], 1 - ShortInt (with range check error on 200)
PSizeInt(Nil)^ := F(200, 200, 100, 100); // Error: Can't determine which overloaded function to call
PSizeInt(Nil)^ := F(200, 200, 200, 100); // mov [eax], 2 - Byte
PSizeInt(Nil)^ := F(200, 200, 200, 200); // mov [eax], 2 - Byte
end;
You could just explicitly specify the type of
24 using a cast, e.g.
F1(B, Byte(24)) - after all, the compiler can't read your mind, so it's better to be explicit in cases like these.