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
@H_502_29@
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
@H_502_29@
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