Delphi如何用积分参数解析重载函数?

考虑以下程序:
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

documentation州(强调我的):

You can pass to an overloaded routine parameters that are not
identical in type with those in any of the routine’s declarations,but
that are assignment-compatible with the parameters in more than one
declaration. This happens most frequently when a routine is overloaded
with different integer types or different real types – for example:

06003

In these cases,when it is possible to do so without ambiguity,the
compiler invokes the routine whose parameters are of the type with the
smallest range that accommodates the actual parameters in the call
.

但这似乎在这里适用。示例代码中的任何过程调用都不接受调用调用中实际参数的类型。

我找不到任何描述编译器遵循的规则的文档。任何人都可以指出这样的文件

这个问题是由以下文章提示的:

> ReverseBytes()
> ZeroConf/Bonjour Code that works in Delphi 7 not working in 2009
> What’s in a Word … ?

更新

由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

两种行为看起来都不符合以下声明:

In these cases,the
compiler invokes the routine whose parameters are of the type with the
smallest range that accommodates the actual parameters in the call
.

解决方法

无符号类型都可以容纳有符号的类型;引用的文档与您的示例是一致的 – 它对编译器将如何对待它们一点也不说。另一方面,签名类型可以容纳一个无符号类型(SmallInt可以容纳字节,LongInt可容纳Word,Int64包含Cardinal):
program IntegerOverloadsPart3;
{$APPTYPE CONSOLE}

procedure Test(Value: ShortInt); overload;
begin
  Writeln('Short');
end;

procedure Test(Value: SmallInt); overload;
begin
  Writeln('Small');
end;

procedure Test(Value: LongInt); overload;
begin
  Writeln('Long');
end;

procedure Test(Value: Int64); overload;
begin
  Writeln('64');
end;

procedure Main;
var
  _byte: Byte;
  _word: Word;
  _cardinal: Cardinal;
  _uint64: UInt64;
begin
  Writeln('Unsigned variables passed as parameters:');
  Test(_byte);
  Test(_word);
  Test(_cardinal);
  Test(_uint64);
  Writeln;
end;

begin
  Main;
  Readln;
end.

Delphi XE输出

Small
Long
64
64

相关文章

ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:...
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂...
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (By...