Что означает ошибка компилятора delphi E2134? - PullRequest
6 голосов
/ 11 августа 2010

В некотором коде, который я исправляю, который интенсивно использует обобщенные и интерфейсные типы, я получаю ошибку

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

Я полагаю, что это потому, что я нахожусь в середине рефакторинга, где некоторые глубокоВложенный набор модулей, которые используют универсальные элементы, не синхронизирован, но ошибка не возникает в месте, где я могу использовать сообщение об ошибке для исправления кода, потому что в коде нет ничего плохого в месте, гдепоявляется ошибка.

Вот контекст, смоделированный, потому что я не могу опубликовать код, его слишком много:

 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.

Похоже, проблема в самом IThingContainer:

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

Выше "const Param" нет информации о типе.На мой взгляд, это странная (подмышка) Паскаля / Дельфи, когда вы полностью нарушаете идею Вирта о строгой типизации.Он примерно так же слабо типизирован, как указатель «void *» в C или тип «Pointer» в Delphi, но он используется редко, кроме как в местах, подобных стандартным функциям RTL пред-объектного паскаля, таких как Move и т. Д.на.По моему мнению, нетипизированные параметры в интерфейсах, используемые в обобщениях, должны быть либо разрешены, либо запрещены, но не разрешены иногда, а запрещены в других случаях.

Это случай, когда особенность Паскаля 1978 года плохо смешивалась сфункция ObjectPascal с 2009 года.

Ответы [ 2 ]

15 голосов
/ 11 августа 2010

Сообщение об ошибке означает, что для данного типа нет информации о типе.

Вот минимальная программа, которая выдает сообщение:

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

Проблема, как представляется, заключается в том, чтоIThingListOf<>, или один из его предков, был скомпилирован с {$M+} active.Исходя из этого, компилятор предполагает, что вы действительно хотите получить полную информацию о типе интерфейса;изначально он использовался SOAP и т. д. для создания заглушек и т. д. Интерфейс RTTI не поддерживает нетипизированные параметры (логически, они не могут быть распределены SOAP и т. д.) - и они отображаются как имеющие тип voidв итоге вы получите это сообщение об ошибке.

Решение состоит в том, чтобы либо не использовать {$M+} - хотя предположительно используется RTTI, в противном случае он не будет включен - либо использовать вместо него, например, Pointer, ипередать адрес явно.

1 голос
/ 11 августа 2010

Сложно сказать об этом, особенно без определения IThingContainer. Если вы закомментируете определение интерфейса, будет ли он компилироваться после этого? Очевидно, что он сломается, когда вы попытаетесь создать класс, который реализует интерфейс, но комментирует ли это проблему эту проблему?

Если так, то компилятор захлебывается чем-то в определении интерфейса. Попробуйте закомментировать некоторые его части, чтобы понять, где проблема. Если нет, то вам придется искать в другом месте.

...