Рассмотрим следующую программу:
program IntegerOverloads;
{$APPTYPE CONSOLE}
procedure WordOrCardinal(Value: Word); overload;
begin
Writeln('Word');
end;
procedure WordOrCardinal(Value: Cardinal); overload;
begin
Writeln('Cardinal');
end;
procedure SmallintOrInteger(Value: Smallint); overload;
begin
Writeln('Smallint');
end;
procedure SmallintOrInteger(Value: Integer); overload;
begin
Writeln('Integer');
end;
procedure ShortintOrSmallint(Value: Shortint); overload;
begin
Writeln('Shortint');
end;
procedure ShortintOrSmallint(Value: Smallint); overload;
begin
Writeln('Smallint');
end;
procedure Main;
var
_integer: Integer;
_cardinal: Cardinal;
_word: Word;
begin
WordOrCardinal(_Integer);
SmallintOrInteger(_cardinal);
ShortintOrSmallint(_word);
end;
begin
Main;
Readln;
end.
Вывод при компиляции XE2:
Cardinal
Integer
Smallint
Вывод при компиляции Delphi 6:
Word
Smallint
Shortint
документация заявляет (основное внимание):
Вы можете перейти к перегруженным параметрам процедуры, которые не являются идентичны по типу с таковыми в любой из стандартных деклараций, но которые совместимы с параметрами в более чем одном декларация. Это происходит чаще всего, когда процедура перегружена с разными целыми типами или разными реальными типами - например:
procedure Store(X: Longint); overload; procedure Store(X: Shortint); overload;
В этих случаях, когда это возможно сделать без двусмысленности, компилятор вызывает процедуру, параметры которой имеют тип с наименьший диапазон, который вмещает фактические параметры в вызове.
Но это, похоже, применимо здесь. Ни один из вызовов процедуры в примере кода не принимает тип, который вмещает фактические параметры в вызове.
Я не могу найти какую-либо документацию, описывающую, какое правило следует компилятору. Может ли кто-нибудь указать мне на такую документацию?
Этот вопрос был вызван следующими статьями:
- ReverseBytes()
- Код ZeroConf/Bonjour, который работает в Delphi 7, не работает в 2009 году
- Что в Word...?
Update
Подсказка от комментариев Кена Уайта, я написал еще одну программу, чтобы проиллюстрировать еще несколько странностей:
program IntegerOverloadsPart2;
{$APPTYPE CONSOLE}
procedure Test(Value: Byte); overload;
begin
Writeln('Byte');
end;
procedure Test(Value: Word); overload;
begin
Writeln('Word');
end;
procedure Test(Value: Cardinal); overload;
begin
Writeln('Cardinal');
end;
procedure Test(Value: Uint64); overload;
begin
Writeln('Uint64');
end;
procedure Main;
var
_byte: Byte;
_shortint: Shortint;
_word: Word;
_smallint: Smallint;
_cardinal: Cardinal;
_integer: Integer;
_uint64: UInt64;
_int64: Int64;
begin
Writeln('Unsigned variables passed as parameters:');
Test(_byte);
Test(_word);
Test(_cardinal);
Test(_uint64);
Writeln;
Writeln('Signed variables passed as parameters:');
Test(_shortint);
Test(_smallint);
Test(_integer);
Test(_int64);
end;
begin
Main;
Readln;
end.
При компиляции с помощью XE2 вывод:
Unsigned variables passed as parameters:
Byte
Word
Cardinal
Uint64
Signed variables passed as parameters:
Uint64
Uint64
Uint64
Uint64
В Delphi 6 мне нужно удалить перегрузку UInt64
, так как этот тип не существует на Delphi 6, выход:
Unsigned variables passed as parameters:
Byte
Word
Cardinal
Signed variables passed as parameters:
Byte
Byte
Byte
И снова ни одно поведение не согласуется с утверждением, что:
В этих случаях, когда это возможно сделать без двусмысленности, компилятор вызывает процедуру, параметры которой имеют тип с наименьший диапазон, который вмещает фактические параметры в вызове.