21

次のプログラムを検討してください。

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;

このような場合、あいまいさなしに実行できる場合、コンパイラは、実際のパラメーターが call に含まれる範囲が最も小さい型のパラメーターを持つルーチンを呼び出します。

しかし、それはここに当てはまるようです。サンプル コード内のプロシージャ コールはどれも、呼び出し内の実パラメータに対応する型を受け入れません。

コンパイラが従う規則について説明しているドキュメントが見つかりません。誰かが私にそのようなドキュメントを教えてもらえますか?

この質問は、次の記事によって促されました。


アップデート

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

UInt64Delphi 6 では、出力が Delphi 6 に存在しないため、オーバーロードを削除する必要があります。

Unsigned variables passed as parameters:
Byte
Word
Cardinal

Signed variables passed as parameters:
Byte
Byte
Byte

この場合も、どちらの動作も次のステートメントと一致していないように見えます。

このような場合、あいまいさなしに実行できる場合、コンパイラは、実際のパラメーターが call に含まれる範囲が最も小さい型のパラメーターを持つルーチンを呼び出します。

4

1 に答える 1

2

unsigned 型は、signed 型に対応できません。引用されたドキュメントはあなたの例と一致しています-コンパイラがそれらをどのように扱うかについては何も述べていません。一方、符号付きの型は符号なしの型に対応できます (SmallInt は Byte に対応し、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
于 2012-09-22T19:24:38.517 に答える