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.
解决方法
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