Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does delphi compiler error E2134 mean?

In some code I am fixing up, which makes heavy use of generics and interfaced types, I am getting error

 E2134, Type '<void>' has no type info.

I believe it is because I am in the middle of a refactor where some deeply nested set of units that all use generics are out of sync, but the error is not happening in a place where I can make use of the error message to fix the code, because there is nothing wrong with the code, at the location where the error is appearing.

Here is the context, mocked up, because I can not post the code, there is too much:

 unit GenericThing;
 ...
 interface
 ...
 type
 ...
 IThingListOf<ThingT> = interface( IThingContainer )
    function  getEnumerator: TEnumerator<ThingT>;
    function  getCount: Integer;
    function  getThing( Index: integer ): ThingT;
    function  getFirst: ThingT;
      function  IndexOf( value: ThingT): integer;
    function  addItem( const Thing: ThingT ): ThingT;
      function  removeItem( const Thing: ThingT ): Integer;
    procedure clear;
    procedure Sort; overload;
    procedure Sort(const AComparer: IComparer<ThingT>); overload;
    property  Count: integer read getCount;
    property  First: ThingT read getFirst;
    property  Items[Index: integer]: ThingT read getThing; default;
  end;

 // error appears on whatever line number comes after the declaration of  IThingListOf<ThingT>...end; 
  function AnythingYouLikeHere:Integer; // there is nothign wrong with this line, but you get the E2134 here.

It appears that the problem is in IThingContainer itself:

   IThingContainer = interface ...
       ...
       procedure DoSomething(const Param);
   end;

THe above "const Param" has no type information. This is a weird (armpit) of Pascal/Delphi in my opinion, where you completely violate Wirth's idea of strong typing. It is about as weakly typed as a "void *" pointer in C, or the "Pointer" type in Delphi, but it is rarely used, except for in places like the standard pre-object-pascal RTL functions like Move, and so on. In my opinion, untyped parameters in interfaces, used in generics, should either be allowed, or disallowed, but not allowed sometimes, and disallowed other times.

This is a case of a Pascal feature from 1978 mixing badly with an ObjectPascal feature from 2009.

like image 902
Warren P Avatar asked Aug 11 '10 13:08

Warren P


1 Answers

The error message means there's no type info available for the given type.

Here's a minimal program which produces the message:

type
  {$M+}
  IThing = interface
    procedure P(const X);
  end;
  {$M-}
begin
end.

The problem, it would appear, is that IThingListOf<>, or one of its ancestors, was compiled with {$M+} active. The compiler presumes from this that you really want full type info for the interface; originally it was used by SOAP etc. support to produce stubs etc. The interface RTTI doesn't support untyped parameters (logically enough, they can't be marshalled by SOAP etc.) - and they show up as being of void type, and you end up with this error message.

The solution is to either not use {$M+} - though presumably the RTTI is being used, otherwise it wouldn't be enabled - or use e.g. Pointer instead, and pass the address explicitly.

like image 164
Barry Kelly Avatar answered Nov 15 '22 06:11

Barry Kelly