Я могу достаточно легко воспроизвести это в XE2, и я думаю, что он будет вести себя так же во всех других версиях. Чтобы упростить это, я сократил это до:
program PointerTypeCompatibility;
{$APPTYPE CONSOLE}
type
A = Integer;
B = Integer;
var
ptA: ^A;
ptB: ^B;
begin
ptA := ptB;
end.
Это также производит E2010. Однако, если вы включите опцию проверенные типом указатели , код будет успешно скомпилирован. Фактически документация об этих опциях компилятора гласит:
В состоянии {$ T-} различные типы указателей, отличные от Pointer, несовместимы (даже если они являются указателями на один и тот же тип). В состоянии {$ T +} указатели на один и тот же тип совместимы.
Спасибо Кену Уайту за указание на полезную тему справки Совместимость типов и идентичность . Соответствующими выдержками являются то, что типы T1 и T2 совместимы с назначением , если:
T1 и T2 являются совместимыми типами указателей.
В документации также указывается, что типы совместимы с типами , если:
Оба типа являются (типизированными) указателями на один и тот же тип, и действует директива компилятора {$ T +}.
Итак, это документирует наблюдаемое поведение и приводит меня к следующему примеру:
program PointerTypeCompatibilityTake2;
{$APPTYPE CONSOLE}
{$TYPEDADDRESS OFF}
var
P1,P2: ^Integer;
P3: ^Integer;
begin
P1 := P2;//compiles
P1 := P3;//E2008 Incompatible types
end.
Итак, подведем итог:
- Когда указатели с проверкой типа отключены, указатели совместимы по присваиванию, если указатели имеют одинаковый тип.
- Когда указатели с проверкой типа включены, указатели совместимы по присваиванию, если указатели указывают на один и тот же тип.
Я должен признаться, что не знаю истории и рассуждений о настройке указателя с проверкой типа, поэтому я не могу предложить никакого объяснения, почему компилятор такой, какой он есть.