パラメータータイプがcharのオープン配列である場合、charの動的な配列は許可されていますか?

StackOverflow https://stackoverflow.com/questions/3781691

質問

私は見ていました Delphi:charとtchararrayの配列「互換性のないタイプ」 そして実験を始めました。私が発見したことはかなり興味深いです。

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.

この単純な小さな例は、オープン配列パラメーターを使用して動的配列を手順に渡す方法を示しています。予想通りにまさにコンパイルして実行されます。

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を実行していますが、それでもまだ起こっています。

役に立ちましたか?

解決

ドキュメントでは、動的配列と互換性があるタイプcharのオープン配列パラメーターに特に言及しているため、これはバグである必要があります。から 「オープン配列パラメーター」:

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

他のヒント

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

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など)に高レベルのタイプを簡単に定義または使用できることがわかりました。 、そしてあなたのコードをより速くします。

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.

問題は、「整数の配列」と矛盾する「チャーの配列」コードが、確かにコンパイラの内在性であることと、PCHEが文字列にタイプキャストできるという事実です。

その理由はそれだと思います 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.

それはおそらく歴史的な理由のためです。
うまくいけば バリー・ケリー また ダニー・ソープ キックインして、これについてさらにフィードバックを提供します。

- ジェロエン

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top