考虑以下程序:
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;
在这些情况下,如果可以毫无歧义地这样做,编译器会调用例程,其参数的类型具有容纳调用中的实际参数的最小范围。
但这似乎适用于此。示例代码中的所有过程调用都不接受容纳调用中实际参数的类型。
我找不到任何描述编译器遵循什么规则的文档。谁能指出我这样的文件?
这个问题是由以下文章提出的:
更新
在 Ken White 评论的提示下,我编写了另一个程序来说明更多的奇怪之处:
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
同样,这两种行为看起来都与以下陈述一致:
在这些情况下,如果可以毫无歧义地这样做,编译器会调用例程,其参数的类型具有容纳调用中的实际参数的最小范围。