11

私はDelphi: array of Char and TCharArray "Incompatible Types"を見ていて、実験を始めました。私が発見したことは、かなり興味深いものです。

procedure Clear(AArray: array of Integer);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := 0;
end;

var
  MyArray: array of Integer;
begin
  Clear(MyArray);
end.

この簡単な例は、Open Array パラメータを使用して動的配列をプロシージャに渡す方法を示しています。期待どおりにコンパイルして実行します。

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
begin
  Clear(MyArray);
end.

これはほぼ同じコードですが、唯一の違いはCharではなくの配列を使用していることですInteger。コンパイルされません。代わりに、コンパイラは次のように吐き出します。

 E2010 Incompatible types: 'Array' and 'Dynamic array'

これはなぜでしょうか?

しばらく検索した後、このQC レポートを見つけました。Delphi 2009 を実行していますが、まだ発生しています。

4

3 に答える 3

4

ドキュメントには、動的配列と互換性のあるChar型のオープン配列パラメーターが具体的に記載されているため、これはバグであるはずです。'Open Array Parameters'から:

function Find(A: array of Char): 整数;
[...]
注: [...]前の例では、動的配列を含む(ただしこれに限定されない)Char要素の任意の配列を受け取る関数を作成します。[...]

于 2010-09-24T01:10:56.343 に答える
4

この種の配列を使用して、独自のタイプを定義できます。

type
  TCharDynArray = array of char;

procedure Clear(AArray: TCharDynArray);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

procedure test;
var
  MyArray: TCharDynArray;
begin
  Clear(MyArray);
end;

このコードは正常にコンパイルされます。もちろん、何も役に立ちません (AArray パラメーターは "var" として設定されていないため、すべてのアイテムに #0 を割り当てる前にスタックにコピーされます)。しかし、少なくとも、それはコンパイルされます。

実際には、動的配列 (TIntegerDynArray など) の高レベルの型を定義または使用する方が簡単であることがわかりました。少なくとも、var を使用して配列を参照として渡すことができるため、スタックにコピーを作成する必要がなくなります。 、コードを高速化します。

PChar へのマッピングについては、すべての動的配列で通常のことです。TIntegerDynArray をポインタにマッピングしてから、それを PInteger または PIntegerArray として使用できます。

procedure AddInteger(var Values: TIntegerDynArray; Value: integer);
var n: integer;
begin
  n := Length(Values);
  SetLength(Values,n+1);
  Values[n] := Value;
end;

procedure Loop(V: PInteger);
begin
  if V<>nil then
    while V^<>0 do begin
      write(V^,' ');
      inc(V); // go to next integer in array
    end;
end;

var IntArray: TIntegerDynArray;
begin
  Loop(pointer(IntArray)); // will display nothing, since pointer(IntArray)=nil for IntArray=[]
  AddInteger(IntArray,2);
  AddInteger(IntArray,3);
  AddInteger(IntArray,0);
  Loop(pointer(IntArray)); // will display '2 3 '  
end.

問題は、「整数の配列」と矛盾する「文字の配列」コードは確かにコンパイラの組み込み関数にあり、PChar を文字列に型キャストできるという事実です。

于 2011-01-06T08:55:46.197 に答える
2

このコードはコンパイルされるため、array of Charと互換性があることが理由だと思います。PChar

procedure Clear(AArray: array of Char);
var
  I: Integer;
begin
  for I := Low(AArray) to High(AArray) do
    AArray[I] := #0;
end;

var
  MyArray: array of Char;
  P: PChar;
begin
  Clear(P^);
end.

それはおそらく歴史的な理由によるものです。Barry KellyまたはDanny Thorpeが参加し、これについてさらにフィードバックを提供してくれることを
願っています。

--jeroen

于 2010-09-23T19:38:50.020 に答える