Что означает ошибка компилятора Delphi E2134?

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

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

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

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

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.
</thingt></thingt></thingt></thingt>

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

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

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

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

2 ответа

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

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

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

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

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


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

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

licensed under cc by-sa 3.0 with attribution.