This section lists all errors that can occur when type checking is performed.
This can happen in many cases:
The variable you’re assigning to is of a different type than the expression in the assignment.
You are calling a function or procedure with parameters that are incompatible with the parameters in the function or procedure definition.
There is no conversion possible between the two types. Another possibility is that they are
declared in different declarations:
Var A1 : Array[1..10] Of Integer; A2 : Array[1..10] Of Integer; Begin A1:=A2; { This statement also gives this error. It is due to the strict type checking of Pascal } End.
The identifier is not a type, or you forgot to supply a type identifier.
This happens when you pass a constant to a routine (such as Inc var or Dec) when it
expects a variable. You can only pass variables as arguments to these functions.
The compiler expects an expression of type integer, but gets a different type.
The expression must be a boolean type. It should be return True or False.
The expression must be of ordinal type, i.e., maximum a Longint. This happens, for
instance, when you specify a second argument to Inc or Dec that doesn’t evaluate to an
ordinal value.
The variable or expression isn’t of the type pointer. This happens when you pass a variable
that isn’t a pointer to New or Dispose.
The variable or expression isn’t of the type class. This happens typically when
This error can occur when the bounds of an array you declared do not evaluate to ordinal
constants.
You are trying to perform an operation on two sets, when the set element types are
not the same. The base type of a set must be the same when taking the union.
several binary operations are not defined for sets. These include: div, mod, **, >= and <=.
The last two may be defined for sets in the future.
An implicit type conversion from a real type to a comp is encountered. Since comp is a 64 bit
integer type, this may indicate an error.
When hints are on, then an integer division with the ’/’ operator will produce this message,
because the result will then be of type real.
When compiling in {$V+} mode, the string you pass as a parameter should be of the exact
same type as the declared parameter of the procedure.
If you declare an enumeration type which has C-like assignments in it, such as in the
following:
Tenum = (a,b,e:=5);
then you cannot use the Succ or Pred functions with this enumeration.
You are trying to read or write a variable from or to a file of type text, which doesn’t
support that variable’s type. Only integer types, reals, pchars and strings can be
read from or written to a text file. Booleans can only be written to text files.
There is at least one set element which is of the wrong type, i.e. not of the set type.
Free Pascal supports an overloaded version of lo/hi for longint/dword/int64/qword which
returns the lower/upper word/dword of the argument. Turbo Pascal always uses a 16 bit
lo/hi which always returns bits 0..7 for lo and the bits 8..15 for hi. If you want the
Turbo Pascal behavior you have to type cast the argument to a word or integer.
You are trying to use a type in an array constructor which is not allowed.
You are trying to pass an invalid type for the specified parameter.
You cannot assign a method to a procedure variable or a procedure to a method pointer.
The constant argument passed to a ln or sqrt function is out of the definition range of these
functions.
It is not possible to get the address of a constant expression, because they are not stored in
memory. You can try making it a typed constant. This error can also be displayed if you try
to pass a property to a var parameter.
Only expressions which can be on the left side of an assignment can be passed as call by
reference arguments.
Remark: Properties can be used on the left side of an assignment, nevertheless they cannot be used as arguments.
It’s not allowed to assign a local procedure/function to a procedure variable, because the
calling convention of a local procedure/function is different. You can only assign local
procedure/function to a void pointer.
It is not allowed to assign a value to an address of a variable, constant, procedure or
function. You can try compiling with -So if the identifier is a procedure variable.
It’s not allowed to assign a value to a variable which is declared as a const. This is normally a
parameter declared as const. To allow changing the value, pass the parameter by value, or a
parameter by reference (using var).
If you are accessing a variable using an index ’[¡x¿]’ then the type must be an array. In FPC
mode a pointer is also allowed.
The compiler expected to encounter an interface type name, but got something else. The
following code would produce this error:
Type TMyStream = Class(TStream,Integer)
If you divide (or calculate the modulus of) a signed expression by a longword (or vice versa),
or if you have overflow and/or range checking turned on and use an arithmetic expression (+,
-, *, div, mod) in which both signed numbers and longwords appear, then everything has to
be evaluated in 64 bit arithmetic which is slower than normal 32 bit arithmetic. You can
avoid this by typecasting one operand so it matches the result type of the other one.
If you use a binary operator (and, or, xor) and one of the operands is a longword while the
other one is a signed expression, then, if range checking is turned on, you may get a range
check error because in such a case both operands are converted to longword before the
operation is carried out. You can avoid this by typecasting one operand so it matches the
result type of the other one.
Type casting to a type with a different size is not allowed when the variable is used in an
assignment.
When you declared an enumeration type which has C-like assignments, such as in the
following:
Tenum = (a,b,e:=5);
There is a typecast from one class or object to another while the class/object are not related.
This will probably lead to errors.
There is a typecast from one class to another while the classes are not related. This will
probably lead to errors.
The compiler expected a class or interface name, but got another type or identifier.
This error occurs when a type is not complete: i.e. a pointer type which points to an
undefined type.
The size of the constant string, which is assigned to a shortstring, is longer than the
maximum size of the shortstring (255 characters).
There is a comparison between a constant and an expression where the constant is out
of the valid range of values of the expression. Because of type promotion, the
statement will always evaluate to false. Explicitly typecast the constant or the
expression to the correct range to avoid this warning if you think the code is correct.
There is a comparison between a constant and an expression where the constant is out
of the valid range of values of the expression. Because of type promotion, the
statement will always evaluate to true. Explicitly typecast the constant or the
expression to the correct range to avoid this warning if you think the code is correct.
An instance of a class is created which contains non-implemented abstract methods. This will
probably lead to a runtime error 211 in the code if that routine is ever called. All abstract
methods should be overridden.
The left operand of the in operator is not an ordinal or enumeration which fits within 8 bits.
This may lead to range check errors. The in operator currently only supports a left
operand which fits within a byte. In the case of enumerations, the size of an element
of an enumeration can be controlled with the {$PACKENUM} or {$Zn} switches.
There is an assignment to a smaller type than the source type. This means that this may
cause a range-check error, or may lead to possible loss of data.
There is an assignment to a smaller type than the source type. This means that this may
cause a range-check error, or may lead to possible loss of data.
An abstract method has no body, so the address of an abstract method cannot be taken.
You are trying to assign a value to a formal (untyped var, const or out) parameter, or to an
open array.
The compiler expects an constant expression, but gets a variable expression.
When doing a type-cast, you must take care that the sizes of the variable and the destination
type are the same.
If you typecast a pointer to a longint (or vice-versa), this code will not compile on a machine
using 64 bits addressing.
If you typecast a pointer to an ordinal type of a different size (or vice-versa), this can cause
problems. This is a warning to help in finding the 32 bit specific code where cardinal/longint
is used to typecast pointers to ordinals. A solution is to use the ptrint/ptruint types instead.
You’re calling overloaded functions with a parameter that doesn’t correspond to any of the
declared function parameter lists. e.g. when you have declared a function with parameters
word and longint, and then you call it with a parameter which is of type integer.
The type of a for loop variable must be an ordinal type. Loop variables cannot be reals or
strings.
In C, constant real values are double by default. For this reason, if you pass a constant real
value to a variable argument part of a C function, FPC by default converts this constant to
double as well. If you want to prevent this from happening, add an explicit typecast around
the constant.
Some operators, such as the AS operator, are only applicable to classes or COM interfaces.
The compiler expects a (bit)packed array as the specified parameter.
The compiler expects a regular (i.e., not packed) array as the specified parameter.
Support for packed arrays of types that need initialization (such as ansistrings, or records
which contain ansistrings) is not yet implemented.
You cannot declare a (bit)packed array as a typed constant at this time.
Addition/subtraction from an untyped pointer may work differently in {$T+}. Use a typecast
to a typed pointer.
The address of a subroutine marked as local cannot be taken.
A subroutine marked as local cannot be exported from a unit.
Only byte, integer, longint, smallint, currency, single, double, ansistring, widestring,
tdatetime, variant, olevariant, wordbool and all interfaces are automatable.
Adding two types can cause overflow errors. Since you are converting the result to a larger
type, you could prevent such errors by converting the operands to this type before doing the
addition.
Subtracting two types can cause overflow errors. Since you are converting the result to a
larger type, you could prevent such errors by converting the operands to this type before
doing the subtraction.
Multiplying two types can cause overflow errors. Since you are converting the result to a
larger type, you could prevent such errors by converting the operands to this type before
doing the multiplication.
The virtual address space on 32 bit machines runs from $00000000 to $ffffffff. Many
operating systems allow you to allocate memory above $80000000. For example
both Windows and linux allow pointers in the range $0000000 to $bfffffff. If you
convert pointers to signed types, this can cause overflow and range check errors,
but also $80000000 ¡ $7fffffff. This can cause random errors in code like ”if p¿q”.
When applying the as-operator to an interface or class, the desired interface (i.e. the right
operand of the as-operator) must have a valid GUID.
An Objective-C selector cannot be empty, must be a valid identifier or a single colon, and if it
contains at least one colon it must also end in one.
A selector can only be created for Objective-C methods, not for any other kind of
procedure/function/method.
A selector can only be created for Objective-C methods, either by specifying the name using
a string constant, or by using an Objective-C method identifier that is visible in the current
scope.
Type information is not generated for some types, such as enumerations with gaps in their
value range (this includes enumerations whose lower bound is different from zero).
The compiler expected a protocol type name, but found something else.
Objective-C and Blocks make extensive use of run time type information (RTTI).
This format is defined by the maintainers of the run time and can therefore not
be adapted to all possible Object Pascal types. In particular, types that depend
on reference counting by the compiler (such as ansistrings and certain kinds of
interfaces) cannot be used as fields of Objective-C classes, cannot be directly passed
to Objective-C methods or Blocks, and cannot be encoded using objc_encode.
It is only possible to create class reference types of class and objcclass
univ parameters are implicitly compatible with all types of the same size, also in procedural
variable definitions. That means that the following code is legal, because single and
longint have the same size:
{$mode macpas} Type TIntProc = procedure (l: univ longint); procedure test(s: single); begin writeln(s); end; var p: TIntProc; begin p:=test; p(4); end.
This code may however crash on platforms that pass integers in registers and floating point values on the stack, because then the stack will be unbalanced. Note that this warning will not flag all potentially dangerous situations. when test returns.
Recursive specializations of generics like Type MyType = specialize MyGeneric<MyType>;
are not possible.
Type parameters are only allowed for methods of generic classes, records or objects
If a class helper inherits from another class helper the extended class must extend either the
same class as the parent class helper or a subclass of it
If a record helper inherits from another record helper it must extend the same record that the
parent record helper extended.
This error occurs when one tries to assign the result of a procedure or destructor call. A
procedure or destructor returns no value so this is not possible.
An implicit type conversion from an ansi string type to an unicode string type is
encountered. To avoid this warning perform an explicit type conversion.
An implicit type conversion from an unicode string type to an ansi string type is
encountered. This conversion can lose data since not all unicode characters may be
represented in the codepage of destination string type.
An explicit typecast from an ansi string type to an unicode string type is encountered. This
warning is off by default. You can turn it on to see all suspicious string conversions.
An explicit typecast from an unicode string type to an ansi string type is encountered. This
conversion can lose data since not all unicode characters may be represented in the codepage
of destination string type. This warning is off by default. You can turn it on to see all the
places with lossy string conversions.
Conversion from a WideChar to AnsiChar can lose data since now all unicode characters may
be represented in the current system codepage You can nest function definitions only 31
levels deep.
Some types like for example Text and File Of X are not supported by the Default intrinsic.
Virtual class methods cannot be static when targeting the JVM platform, because the self
pointer is required for correct dispatching.
It is only possible to assign a value to a final (class) field inside a (class) constructor of its
owning class.
On managed platforms, untyped parameters are translated by the compiler into
the equivalent of var x: BaseClassType. Non-class-based types passed to such
parameters are automatically wrapped (or boxed) in a class, and after the call the
potentially modified value is assigned back to the original variable. On the caller side,
changing untyped var/out parameters happens by simply assigning values to them
(either class-based or primitive ones). On the caller side, they will be extracted and
if their type does not match the original variable’s, an exception will be raised.
Managed platforms guarantee type safety at the bytecode level. This means that the virtual
machine must be able to statically determine that no type-unsafe assignments or
operations occur. By assigning a parent class type to a variable of a child type by
typecasting the assignment side to the parent class type, the type safety would no longer
be guaranteed and the generated code would fail verification at run time time.
All methods in an interface have always public visibility. That means that if an interface
method is implemented using a (strict) protected or private method, this method is actually
publicly accessible via the interface. On the JVM target this situation results in an error
because the JVM rejects such attempts to circumvent the visibility rules. On other targets
this is a warning that is disabled by default because such situations are common practice, but
it can be enabled in case you are concerned with keeping your code compilable for the JVM
target.
Typeof() intrinsic returns pointer to VMT of its argument. It cannot be used on object types
that do not have VMT.
Parameters declared as structured types, such as files, variants, non-dynamic arrays and
TP-style objects, cannot have a default value.
Types like procedural variables cannot be extended by type helpers
In certain i8086 memory models (medium, large and huge), procedures and functions have to
be declared ’far’ in order to allow their address to be taken.
The specified class is declared as abstract and thus no instance of this class should be
created. This is merely a warning for Delphi compatibility.
Subroutine references can refer to any kind of subroutine and hence do not require
specialisation for methods or nested subroutines.
If a set is constructed like this: s:=[9..7];], then an empty set is generated. As this is
something normally not desired, the compiler warns about it.
When declaring a C block reference ensure that it uses either the cdecl or mwpascal calling
convention either by adding the corresponding function directive or by using the {$Calling}
compiler directive.
When declaring an interface forward, the interface type must be the same as at the actual
declaration of the interface. This is in particular important with regard to the
parent interface which implicitly sets the interface type for the child interface.
Only types that can also be used (indirectly) for untyped constants can be used as a type for
a generic constant parameter.
You are trying to read or write a variable from or to a file of type text, which
doesn’t support that variable’s type in the selected language mode (iso mode).
ISO Pascal requires that string constants have the same length as the array to which them
they are assigned.
Function references can live beyond the scope of the function they’re contained in while
nested functions assigned to nested function variables can’t. Due to this discrepancy in
design assigning a nested function variable to a function reference is forbidden.
WebAssembly externref types don’t have an in-memory representation and therefore, their
address cannot be taken.
WebAssembly reference types are opaque, meaning neither their size, nor their bit pattern
can be observed.