Delphi Generics: Problem 1

Kids, don’t try this at home :)

class procedure DynamicArray<T>.Test();
var
  Arr : array of T;
begin
  { Fails miserably! }
end;

Error:
[DCC Fatal Error] Tests.DynamicArray.pas(772): F2084 Internal Error: URW1135

There you have it :)

The fix is rather simple but annoying:

Declare a new type in the class/record like this:

type
  DynamicArray<T> = class
  private
  type
    TArrayOfT = array of T;

  public
    { Lots of stuff here }
end;

And then simply make the variable Arr to be TArrayOfT:

class procedure DynamicArray<T>.Test();
var
  Arr : TArrayOfT;
begin
  { Works! }
end;

Till the next bug.

6 Responses to 'Delphi Generics: Problem 1'

  1. Barry Kelly says:

    Works for me:

    unit local_dynarray;

    interface

    type
    C<T> = class
    class procedure M;
    end;

    implementation

    class procedure C<T>.M;
    var
    x: array of T;
    begin
    end;

    end.

    Can you create a complete example that shows the problem? Or better yet, a logged QC number?

  2. alex says:

    Hi Barry, I saw a similar report in QC. But anyway, just tried to reproduce this simple problem with this code:

    TMan = class
    public
    procedure X();
    end;

    procedure TMan.X;
    var
    A : array of T;
    begin

    end;

    var
    d : TMan;

    The interesting part is that it will work in a new project. If I instead add this class to an existing class collections lib i’m working on it will throw that error. Hell, even if I add a simple “Arr: array of T” in an method of any generic class I am working on it will throw that error. Sorry can’t get you a better report because I can’t get a guaranteed result.

    Note: When I rebuild the whole package every time it will not throw this error but when I just compile it will throw it 1 time every two tries.

    Note 2: Sometime this error pops up in the lib package, other times in the exe application that tests it (DUnit).

    You can try out the libs I am talking about at: http://code.google.com/p/delphilhlplib/

    I’ve found other interesting internal errors but those are reported in QC already.

    Big regards, Alex.

  3. Panagiotis says:

    I get the same error with YAWE source code in Delphi 2009.

    [DCC Fatal Error] Components.NetworkCore.World.pas(685): F2084 Internal Error: URW1135

    It does not seem generics to be the problem (no generics in YAWE as you know).

    Off topic: It was a pleasant experience to work with YAWE source code while trying to convert it for Delphi 2009, even though there were so many things to change to make it work, I got enlighted and ashamed to even say I know Delphi.
    Good work.

  4. alex says:

    Thanks!

    As for your problem, try to disable the Inlining in project options. IIRC URW1135 is related to inlining.

    Note: There are some bugs in the network and tick components of YAWE :)

    Alex.

  5. Panagiotis says:

    While trying to create a thread safe TMultiMap from DelphiHelpLib I ended again with the same internal error.
    The weird thing is that if I remove (comment) the internal multimap storage or if the class has no function/procedure that will produce code by the compiler, I get no error.

    No error (only declaration without actual code present):
    type
    TThreadMultiMap = class
    private
    FMultiMap: TMultiMap;
    end;

    Error:
    type
    TThreadMultiMap = class
    private
    FMultiMap: TMultiMap;
    protected
    function GetCount() : Cardinal;
    public
    property Count : Cardinal read GetCount;
    end;

    function TThreadMultiMap.GetCount: Cardinal;
    begin
    // actually any code gives error
    Result := FMultiMap.Count; // if you comment this line it compiles
    end;

    or some other code that does not access internal multimap:

    function TThreadMultiMap.GetCount: Cardinal;
    begin
    // actually any code gives error
    Result := Cardinal(Self); // if you comment this line it compiles
    end;

    Even if I disable inlining still the same error. But thread safe classes for TArraySet, TDictionary, TLinkedList, TList, TQueue and TStack compile without any error or warning. If you want the full unit (and the rest working thread safe classes) tell me to put it somewhere or send it to your email.
    I hope the compiler team (I have faith on them) will fix these errors because for the moment generics are only playground.

    I just noticed http://qc.embarcadero.com/wc/qcmain.aspx?d=70249
    So the use of virtual functions/procedures override and enable inlining in the project and inlining cause problems with generics.

    About YAWE, latest rev from svn has so many errors, unit names are different in source code than in filenames, debug helper source code is missing and many other like that. Anyway YAWE is pretty amazing (and a good project to learn alot of things) even if I cannot make it compile (yet).

    Thanks again for YAWE and DelphiHelpLib,
    Panagiotis.

  6. alex says:

    I would suggest you use d2006 to compile YAWE. D2009 still has problems with a lot of stuff (mainly generics related).

    I haven’t worked on YAWE for a few years now, and I’m pretty sure there are other hidden errors there too. Try to use it as a learning code and not as much as a functioning piece of software.

Leave a Reply

Your email address will not be published.