Last night I had a really strange compiler error when I tried to translate my new array record. You have to know that I have rewritten the complete record and added generic support to it. Here is a lil’ bit of the code which you need to unterstand why I got this error.
TApArray<T> = record public type TArrayPosition = (apBegin, apEnd, apIndex); private FData : TArray<T>; public function TApArray<T>.Add(const Items: TArray<T>; const APosition: TArrayPosition = apEnd; const Index: Integer = -1): TArray<T>; { ... } end; { ... } function TApArray<T>.Add(const Items: TArray<T>; const APosition: TArrayPosition = apEnd; const Index: Integer = -1): TArray<T>; var i : Integer; L : Integer; begin if (APosition = apIndex) and ((Index < 0) or (Index > Length() - 1)) then raise Exception.Create('Index out of range.'); { ... } end;
When I wanted to compile the source Delphi gave me the following error message and jumped to the end of the source file:
[DCC Fatal Error] Project1.dpr(1): F2084 Internal Error: AV221E0FCF-R0000000C-0
I wondered what that message wanted to tell me because I’ve never seen that before. So I asked the most-used web search engine because I had definitely no idea why I got this message – Delphi didn’t even jump to the position where the problem was. But there were no answers, not a single page mentions this error.
After some time I found the position of the error: the first usage of an element of TArrayPosition
. Well, when I commented the line with the if
in the Add() method there was no error message any more. After some time of thinking about the problem it was clear: the problem was that I have declared the type TArrayPosition
as a class type of TApArray<T>
.
For every instance of TApArray<T>
this would lead to a new class type TArrayPosition
which itself would not result in a problem yet. But what about the usage of an element? And exactly here is the problem: in my example above the apIndex
is not unique any more because there are more versions of TArrayPosition
and so there are more versions of apIndex
. The compiler can’t know to which type apIndex
belongs to so it throws this error message.
Now, what are possible solutions for this problem? I think there are two ways how to fix it:
- Instead of using
apIndex
you can useTApArray<T>.TArrayPosition.apIndex
which addresses a unique element of a specific instance ofTArrayPosition
. But you have to write more code than you really want to. Especially there is no reason to do this for a public class type. But when you want to use a (strict) private class type this is the solution you should choose. - The second solution is not to declare
TArrayPosition
as a class type but as a normal type like this:TArrayPosition = (apBegin, apEnd, apIndex); TApArray<T> = record { ... } end;
This should be the preferred version when you don’t need a private type.