Am 22.04.2022 um 20:51 schrieb Martin Frb via fpc-pascal:
I created a little test program (see bottom of mail).

And it gives a strange warning:

Compile Project, Target: C:\Users\martin\AppData\Local\Temp\project1.exe: Success, Warnings: 1, Hints: 3 project1.lpr(67,52) Warning: Range check error while evaluating constants (100000 must be between -128 and 127)
project1.lpr(41,18) Hint: Local proc "Add$1" is not used
72 lines compiled, 0.2 sec, 105136 bytes code, 5476 bytes data

Line 41 is the declaration of the generic
   generic function Add<T>(aArg1, aArg2: T): T;

So why does it generate "Add$1" if it does not use it? (Or rather why does it warn, if this is some internal details?)

Add$1 is the symbol of the generic itself, *not* the specialization. But please report it, cause that definitely shouldn't be the case anyway, as the generic is after all used by the specializations (and I should compile with -vh more often...)


--------------------------------
And if you add to the app (at the top)

function Add(aArg1, aArg2: Int64): Int64; overload;
begin
//  write(' Int64 overload ');
  Result := aArg1 + aArg2;
end;

Then the line  (Shortint, because the first param is ShortInt)
 writeln('#### 1,CK = ',Add(0, 100000) ); // ShortInt

Will no longer call the specialized function, but instead use the int64 version.

Correct, because a matching non-generic variant is available and the compiler then picks that.


If you comment all "Add(...)" calls, except that one
=> Then you get an additional hint: "project1.lpr(81,41) Hint: Local proc "Add$1$crc9AB0BCED" is not used" So then that very line generates a specialized version for the call, and then the compiler does not use it.

The compiler essentially works like this: it generates a suitable set of overloads. This includes the non-generic routines as well as all generic routines for which suitable type parameters can be found. Out of this set the compiler will then pick the function it will finally use with a preference for non-generic functions (even if parameters might be a worse, though not incompatible match).

That said: if the compiler does not pick one of the specializations it should totally discard them, so please report a bug for this as well.



Yet if INSTEAD of adding the hardcoded Int64 variant (as given above), I let the compile create a Int64 version by adding
    writeln('#### 1,CK = ',Add(int64(0), 100000) ); // ShortInt
before the line above... Well the line above will not use that int64 version, but use its own specialization...

The compiler determines the generic type parameters for each call. In this case it will be Int64 due to the typecast. However that will not change what the other, previous Add calls use and it also won't affect one any following Add call, cause it will simply determine the set of elligible functions (and other implicit specializations as well as explicit specializaitons are *not* part of this) and then determine which one to call out of this set (the compiler might specialize the same generic function with the same generic type parameters multiple times then, but the part that's dealing with specializations in general will detect that and point to the existing symbol instead).

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to