Delphi如何用积分参数解析重载函数? [英] How does Delphi resolve overloaded functions with integral parameters?

查看:128
本文介绍了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编译时的输出是:

The output when compiled by XE2 is:

Cardinal
Integer
Smallint

Delphi 6编译时的输出是:

The output when compiled by Delphi 6 is:

Word
Smallint
Shortint

文档状态(强调我的):


你可以传递一个不重要的例程参数,不是
类型相同与那些在例程的任何声明中,但
与多个
声明中的参数分配兼容。当例行程序重载
时,最常见的情况是使用不同的整数类型或不同的实际类型 - 例如:

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:

procedure Store(X: Longint); overload;
procedure Store(X: Shortint); overload;

在这些情况下,如果有可能这样做没有歧义,
编译器调用参数为类型的例程,
最小的范围适应调用中的实际参数

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.

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

But that does seem to apply here. None of the procedure calls in the example code accept a type that accommodates the actual parameters in the call.

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

I cannot find any documentation that describes what rule the compiler follows. Can anyone point me to such documentation?

此问题由以下文章提示:

This question was prompted by the following articles:

  • ReverseBytes()
  • ZeroConf/Bonjour Code that works in Delphi 7 not working in 2009
  • What's in a Word ... ?

由Ken White的评论提出,我写了另一个程序来说明一些更多的错误:

Prompted by Ken White's comments, I wrote another program to illustrate some more oddities:

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编译时,输出为:

When compiled by XE2 the output is:

Unsigned variables passed as parameters:
Byte
Word
Cardinal
Uint64

Signed variables passed as parameters:
Uint64
Uint64
Uint64
Uint64

在Delphi 6中,我必须删除 UInt64 重载,因为Delphi 6中不存在该类型,输出是:

On Delphi 6 I have to remove the UInt64 overload since that type does not exist on Delphi 6 the output is:

Unsigned variables passed as parameters:
Byte
Word
Cardinal

Signed variables passed as parameters:
Byte
Byte
Byte

再次,这两种行为与以下语句一样: / p>

Again neither behaviour looks consistent with the statement that:


在这些情况下,如果可以这样做不含歧义,
编译器将调用其参数为类型,
最小范围适应调用中的实际参数


推荐答案

无符号类型可以容纳签名类型;引用的文档与您的示例是一致的 - 它对编译器将如何对待它们一点也不说。另一方面,签名类型可以容纳一个无符号的类型(SmallInt可以容纳字节,LongInt适应Word,Int64适配Cardinal):

Neither unsigned type can accommodate a signed type; the documentation quoted is consistent with your examples - it just says nothing about how the compiler will treat them. On the other hand a signed type can accommodate an unsigned type (SmallInt accomodates Byte, LongInt accomodates Word, Int64 accomodates 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输出:

Delphi XE output:

Small
Long
64
64

这篇关于Delphi如何用积分参数解析重载函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆