[fpc-devel] New feature announcement: constant parameters for generics

Sven Barth pascaldragon at googlemail.com
Sun Apr 26 00:13:21 CEST 2020

The Free Pascal team is happy to announce the addition of a new language 
feature: constant parameters for generics.

This allows to declare generic types or routines that aside from type 
parameters can also take constant parameters that can be used inside the 
generic as if one would use untyped constants. Together with inlining 
and optimizations this allows to generate optimal code that is yet flexible.

This feature was developed by Ryan Joseph. Thank you very much Ryan for 
your contribution and your patience until this feature was included.

A generic constant parameter is declared like this:

IDLIST::=<ID>[, <ID>]

The following types are supported for constant parameters:
- integer types (including range types)
- floating point types
- string types
- set types
- enum types
- Boolean types
- Pointer types

While the type declaration might look like a typed constant it is in 
fact an untyped constant. The type is used to allow the author of a 
generic to restrict the range of the type. This has some implications:

- the constant parameter can be used inside the generic whereever an 
untyped constant can be used (e.g. variable initializers, constant 
initializers, default parameters, array indices, compile time intrinsics 
and operations)
- types that can't be used for untyped constants can't be used for 
generic constant parameters either


=== code begin ===

{$mode objfpc}

   generic TStaticArray<T; const N: Integer> = array[0..N-1] of T;

generic function TimesX<const N: Integer>(aArg: Integer): Integer;
   Result := aArg * N;

   myArray: specialize TStaticArray<LongInt, 2>;
   i: LongInt;
   i := specialize TimesX<2>(21);

=== code end ===

Important: Unlike C++ FPC does not support default specializations, thus 
doing recursive specializations together with operations on constants 
will result in out of stack exceptions or infinite loops:

=== code begin ===

{$mode objfpc}

   generic TTest<const N: Integer> = class
     N1 = N - 1;
     TSubTest = specialize TTest<N1>;
     // the following does not work currently for a different reason:
     // TSubTest = specialize TTest<N - 1>;


=== code end ===

Delphi compatibility: this feature is NOT Delphi compatible. However to 
not inconvience users that prefer mode Delphi this feature is also 
available in that mode as our stance usually is that Delphi code should 
compile with FPC while the inverse is not necessarily true.

Also this feature will NOT be part of 3.2.

Please give the generic constant parameters a try and report bugs in the 


More information about the fpc-devel mailing list